You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #364, which covers U+0000 in item data (keys, values, names). Two metadata paths on the PostgreSQL backend still return 500 where the service answers otherwise. Measured against DynamoDB on 2026-09-18 with parameter_validation=False so the service, not the SDK, decided:
request
service
PostgreSQL
SQLite
MongoDB
CreateTable with U+0000 inside the partition key attribute name
200, table ACTIVE, DescribeTable returns the name byte-identical
500 InternalServerError
200
200
CreateTable with U+0000 inside a GSI key attribute name
200
500 InternalServerError
200
200
CreateTable with U+0000 inside the GSI name
400 ValidationException, pattern [a-zA-Z0-9_.-]+ at globalSecondaryIndexes.1.member.indexName
400, same class of message
400
400
CreateTable with U+0000 inside the table name
400 ValidationException, pattern [a-zA-Z0-9_.-]+ at tableName
500 InternalServerError: Internal error during authorization
400
400
Mechanism
Key attribute names: the catalog stores key_schema and attribute_definitions as jsonb (crates/storage-postgres/src/create_table.rs, update_table.rs), and jsonb rejects the \u0000 escape. The data table DDL does not embed the attribute names (key columns are named pk, sk_s, and so on), so the failure is the catalog insert alone.
Table name: authorization runs before the table name pattern is validated. It builds the resource ARN from the request's table name and the policy cache fetches the resource tags for that ARN (fetch_resource_tags in crates/server/src/authorization.rs); on PostgreSQL the ARN is a TEXT parameter, PostgreSQL rejects the 0x00 byte, and op_err_to_dynamo turns the store error into InternalServerError: Internal error during authorization. SQLite and MongoDB run the same lookup without error and then fail validation as the service does.
Expected
Key schema attribute names containing U+0000 are stored and returned on PostgreSQL. The escape from [Bug] PostgreSQL and MongoDB: an item containing U+0000 returns InternalServerError; the service accepts it #364 (extenddb_storage::util::escape_control) applied to the catalog JSON on write and reversed on read covers it; the ~20 serde_json::from_value sites that read key_schema and attribute_definitions in the PostgreSQL crate would go through one helper.
A table name containing U+0000 gets the service's ValidationException on every backend. Either the table name pattern is checked before authorization is evaluated (the service's order, and what the other two backends effectively do), or the authorization store escapes the name.
Summary
Follow-up to #364, which covers U+0000 in item data (keys, values, names). Two metadata paths on the PostgreSQL backend still return 500 where the service answers otherwise. Measured against DynamoDB on 2026-09-18 with
parameter_validation=Falseso the service, not the SDK, decided:InternalServerErrorInternalServerErrorValidationException, pattern[a-zA-Z0-9_.-]+atglobalSecondaryIndexes.1.member.indexNameValidationException, pattern[a-zA-Z0-9_.-]+attableNameInternalServerError: Internal error during authorizationMechanism
Key attribute names: the catalog stores
key_schemaandattribute_definitionsasjsonb(crates/storage-postgres/src/create_table.rs,update_table.rs), andjsonbrejects the\u0000escape. The data table DDL does not embed the attribute names (key columns are namedpk,sk_s, and so on), so the failure is the catalog insert alone.Table name: authorization runs before the table name pattern is validated. It builds the resource ARN from the request's table name and the policy cache fetches the resource tags for that ARN (
fetch_resource_tagsincrates/server/src/authorization.rs); on PostgreSQL the ARN is aTEXTparameter, PostgreSQL rejects the 0x00 byte, andop_err_to_dynamoturns the store error intoInternalServerError: Internal error during authorization. SQLite and MongoDB run the same lookup without error and then fail validation as the service does.Expected
extenddb_storage::util::escape_control) applied to the catalog JSON on write and reversed on read covers it; the ~20serde_json::from_valuesites that readkey_schemaandattribute_definitionsin the PostgreSQL crate would go through one helper.ValidationExceptionon every backend. Either the table name pattern is checked before authorization is evaluated (the service's order, and what the other two backends effectively do), or the authorization store escapes the name.