When inserting or assigning a bit string literal that is shorter than the column's declared BIT(n) length, PostgreSQL issues a warning with SQLSTATE 01008 and condition name implicit_zero_bit_padding:
WARNING: implicit zero bit padding
PostgreSQL silently extends the value by appending 0 bits on the right until it reaches the declared width, then continues the operation. The value is stored successfully — this is a warning, not an error.
What This Error Means
SQLSTATE class 01 represents warnings in the SQL standard. Code 01008 specifically flags implicit zero-bit padding, a behavior that silently modifies the bit string you provided before storing it. Unlike class 22 data exceptions (which abort the operation), a class 01 warning is informational: the statement completes, the row is written, but PostgreSQL wants you to know the stored value differs from what you literally typed.
PostgreSQL's fixed-length BIT(n) type requires every stored value to be exactly n bits wide. When a shorter literal like B'101' is assigned to a BIT(8) column, PostgreSQL pads it on the right with zeros to produce 10100000. The padding follows the SQL standard's right-padding rule for bit strings, analogous to how CHAR(n) right-pads with spaces.
The warning is raised at the point of assignment — during INSERT, UPDATE, or a CAST expression — and is visible in the client that executed the statement. The transaction remains open and in a clean state; no rollback is needed. However, if you were not expecting the padding, the stored value may not represent the bit pattern you intended.
Common Causes
Inserting a shorter bit literal into a
BIT(n)column. WritingB'1'into aBIT(8)column stores10000000, not00000001. If the column represents flags or a bitmask where bit position matters, right-padding changes the semantics.Casting a
BIT VARYINGvalue to a fixed-lengthBIT(n)type when the source value is shorter thann. This can happen in type casts inside views, generated columns, or function return types declared asBIT(n).Application code constructing bit strings dynamically and producing a value shorter than the schema declares — for example, trimming leading/trailing characters from a hex or binary string before passing it to PostgreSQL.
Migrating data between schemas where the source column was
BIT VARYINGand the target is a fixed-lengthBIT(n)with a larger declared width.
How to Fix implicit_zero_bit_padding
Left-pad the literal to the exact declared width before inserting. If you want the value
1to occupy bit position 0 (the least-significant position in your encoding), pad with leading zeros:-- Column declared as BIT(8) INSERT INTO flags (bits) VALUES (B'00000001');Use
LPADon a text representation and then cast, if constructing the value programmatically:INSERT INTO flags (bits) VALUES (LPAD('101', 8, '0')::bit(8)); -- stores 00000101Switch to
BIT VARYING(n)if you do not need a fixed width.VARBITstores only the bits you provide and does not pad:-- No padding warning; stores exactly 3 bits CREATE TABLE flags (bits BIT VARYING(8)); INSERT INTO flags (bits) VALUES (B'101');Suppress the warning only after confirming the padding is intentional. If right-padding is semantically correct for your use case (for example, the column stores a bitmask read left-to-right), acknowledge the behavior explicitly in code comments and consider adding a check constraint to document the intent.
Audit existing data after schema changes. If the warning appeared after widening a
BIT(n)column, verify that existing rows were padded consistently withSELECT bits, length(bits) FROM your_tablebefore the application resumes writes.
Additional Information
- The
implicit_zero_bit_paddingcondition is defined in the SQL:1999 standard and has been present in PostgreSQL since bit-string type support was added. It is not a recent regression. - Related SQLSTATE codes in the
01(Warning) class include01003(null value eliminated in set function),01006(privilege not revoked), and01007(privilege not granted). None of these abort the current transaction. - The counterpart for strings is
CHAR(n)space-padding, which does not emit a warning — PostgreSQL only warns for bit strings because the semantic impact of padding is more likely to be unintentional. - Most PostgreSQL drivers expose SQLSTATE
01008as a warning-level notice rather than an exception. In Python'spsycopg2/psycopg3, it surfaces via the connection'snoticeslist. In JDBC, it appears throughSQLWarning. Applications that ignore driver-level warnings will not see it at all. - There is no GUC (configuration parameter) to promote this warning to an error, unlike some other notice conditions. If you want to enforce exact-width bit strings, add a
CHECK (length(bits) = n)constraint — though that will reject short values rather than pad them.
Frequently Asked Questions
Why does PostgreSQL store 10000000 when I insert B'1' into a BIT(8) column?
PostgreSQL follows the SQL standard's right-padding rule for bit strings. It appends 0 bits to the right of your literal until the value is exactly 8 bits. If you intended the value 1 to be in the least-significant position (i.e., 00000001), you need to left-pad the literal explicitly before inserting.
Is the data corrupted or the transaction rolled back?
No. SQLSTATE 01008 is a warning, not an error. The row is written successfully with the padded value. The transaction remains open and valid. You only need to act if the padded value is semantically wrong for your application.
How do I avoid this warning without changing my schema?
Pad the bit string in your query to match the declared column width before the value reaches PostgreSQL. Use LPAD(value, n, '0')::bit(n) for programmatic values, or write full-width literals (e.g., B'00000001' instead of B'1').
Should I use BIT(n) or BIT VARYING(n)?
Use BIT(n) only when every value must occupy exactly n bits — for example, fixed-width protocol fields. Use BIT VARYING(n) (alias VARBIT) when values have different lengths and you want to store them as-is without padding. VARBIT never raises 01008.