Incident brief
String data length mismatch
A bit string value was stored into a bit(n) column whose length didn't exactly match n. PostgreSQL rejected the write instead of guessing how to fit it.
What lands in your log
ERROR: bit string length 2 does not match type bit(3)
In 10 seconds
- What triggers it
- Create a table with a fixed-length bit(3) column.
- Fix
- Supply a bit string whose length exactly matches the column's declared length.
- Proof
- Reproduced on PostgreSQL 16.14 → Inserting a 2-bit value into a bit(3) column was rejected with SQLSTATE 22026, naming both the supplied length and the declared length. The session was unaffected afterward.
Fix
What to do right now
Application-level steps for this error.
- Supply a bit string whose length exactly matches the column's declared length.
- If you intentionally want truncation/padding instead of an error, that's a different, explicit operation, see the counterexample for what it actually does and why it's risky.
- Prefer bit varying(n) over bit(n) if the true length legitimately varies.
-- Use equal-length bit strings for bitwise operations.
SELECT B'101' & B'010' AS matched_length;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
String data length mismatch (22026) is statement-local: PostgreSQL does not retain the rejected value after the statement ends. Capture the exact bound value and statement position in application/server logs, then run this targeted validation before retrying.
Compare bit-string operand lengths
Validate the specific value/shape that can raise this SQLSTATE.
SELECT bit_length(B'101') AS left_bits,
bit_length(B'10') AS right_bits,
bit_length(B'101') = bit_length(B'10') AS lengths_match;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, Bit String Types
bit type data must match the length n exactly; it is an error to attempt to store shorter or longer bit strings.Read the full section on postgresql.org →
The length-mismatched insert
Per the manual's own worked example, bit(n) requires an exact length match on insert, B'10' is 2 bits, the column needs exactly 3, so PostgreSQL rejects the write rather than guessing how to pad or truncate it.Confirming the session still works
The rejected insert didn't affect the session, the next statement ran normally.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Create a table with a fixed-length bit(3) column.
- 2INSERT a bit string that is shorter (or longer) than 3 bits.
- 3SQLSTATE 22026 is reported, naming the exact lengths involved.
One client: create a bit(3) column, then insert a bit string of the wrong length.
-- No table is required; the error comes from unequal bit-string operands.SELECT B'101' & B'10';
SELECT 1 AS session_still_alive;SELECT 1 AS session_still_alive;What PostgreSQL actually returned
CREATE TABLEERROR: bit string length 2 does not match type bit(3) session_still_alive
----------------------
1
(1 row)A developer hitting this error might reach for an explicit ::bit(3) cast on the value, assuming it validates the length the same way INSERT does. That assumption was tested directly against the exact value that failed above.
Without this
Above: inserting a wrong-length bit string into a bit(3) column is rejected with SQLSTATE 22026.
With this, tested
Below: explicitly casting a wrong-length bit string to bit(3) does NOT error, it silently truncates.
- A second operational test: exact SQL, raw output, measured result, and engineer notes
- Fix that only partly works, and fails under a different code when it doesn't: exact SQL, output, and verdict
- A manual-grounded production interpretation of the lab result
Card required. Cancel before day 7 and you are not charged.
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Verification scope
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed
Went further?
Pro unlocks the second lab proof
Free page stops the bleeding. Pro adds the operational test, SQLSTATE audit, and deeper evidence, same error, more certainty.