This error occurs when PostgreSQL receives a value that doesn't match the UUID format (FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF). Common causes include empty strings, malformed UUIDs, or passing non-UUID data types to UUID columns.
PostgreSQL's UUID type enforces strict validation on input values. When you attempt to insert, update, or cast a value to UUID type, PostgreSQL checks whether it conforms to the standard UUID format: 32 hexadecimal digits displayed in five groups separated by hyphens (8-4-4-4-12 format). This error indicates that the value provided doesn't meet these requirements. PostgreSQL accepts UUIDs in various forms (with or without hyphens, upper or lowercase, with braces), but the underlying data must represent a valid 128-bit UUID. The error message typically includes the invalid value, such as "invalid input syntax for type uuid: \"\"" for empty strings or "invalid input syntax for type uuid: \"abc123\"" for malformed values. The validation happens at the database level before any data is written, protecting data integrity but requiring careful handling of UUID values in application code.
Check what value is being passed to the UUID column. The error message usually shows the invalid value:
ERROR: invalid input syntax for type uuid: ""
HINT: valid UUID values are of the form 'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'Valid UUID formats accepted by PostgreSQL:
- Standard: 550e8400-e29b-41d4-a716-446655440000
- Uppercase: 550E8400-E29B-41D4-A716-446655440000
- Without hyphens: 550e8400e29b41d4a716446655440000
- With braces: {550e8400-e29b-41d4-a716-446655440000}
If you see an empty string or malformed value, trace back to where this value originates in your application code.
If you don't have a UUID value yet, pass NULL instead of an empty string:
Node.js/JavaScript:
// Wrong
const userId = "";
await db.query('INSERT INTO users (id, name) VALUES ($1, $2)', [userId, name]);
// Correct
const userId = null; // or undefined, depending on your ORM
await db.query('INSERT INTO users (id, name) VALUES ($1, $2)', [userId, name]);Python/Django:
# Wrong
User.objects.create(id="", name="John")
# Correct
User.objects.create(id=None, name="John") # Let database generate UUIDLaravel/PHP:
// Wrong
User::create(['id' => '', 'name' => 'John']);
// Correct
User::create(['id' => null, 'name' => 'John']);Use PostgreSQL's built-in UUID generation functions or your programming language's UUID library:
PostgreSQL default value:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL
);Note: Remove quotes around uuid_generate_v4() if using the uuid-ossp extension:
-- Wrong (treats it as a string literal)
id UUID DEFAULT 'uuid_generate_v4()'
-- Correct
id UUID DEFAULT uuid_generate_v4()JavaScript/Node.js:
const { v4: uuidv4 } = require('uuid');
const newId = uuidv4(); // e.g., '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'Python:
import uuid
new_id = uuid.uuid4() # Returns UUID object
new_id_str = str(uuid.uuid4()) # Returns stringAdd validation in your application layer to catch invalid UUIDs before they reach the database:
JavaScript/TypeScript:
function isValidUUID(str) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
return uuidRegex.test(str);
}
const userId = req.params.id;
if (!isValidUUID(userId)) {
return res.status(400).json({ error: 'Invalid UUID format' });
}PostgreSQL function:
-- Try casting and return NULL if invalid
CREATE OR REPLACE FUNCTION safe_uuid(text) RETURNS uuid AS $$
BEGIN
RETURN $1::uuid;
EXCEPTION WHEN invalid_text_representation THEN
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- Usage
SELECT safe_uuid('invalid-uuid'); -- Returns NULLIf migrating from bigint or varchar to UUID, convert the data explicitly:
Migrating bigint to UUID (not recommended, but sometimes necessary):
-- Add new UUID column
ALTER TABLE users ADD COLUMN new_id UUID DEFAULT gen_random_uuid();
-- Copy data (creates new UUIDs; you can't convert bigint to meaningful UUIDs)
UPDATE users SET new_id = gen_random_uuid();
-- Drop old column and rename
ALTER TABLE users DROP COLUMN id;
ALTER TABLE users RENAME COLUMN new_id TO id;Converting varchar/text that contains valid UUIDs:
-- Verify all values are valid UUIDs first
SELECT id FROM users WHERE id::text !~ '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$';
-- If empty result, safe to convert
ALTER TABLE users ALTER COLUMN id TYPE UUID USING id::uuid;UUID Extensions:
PostgreSQL offers two UUID generation extensions:
- gen_random_uuid() (built-in since PostgreSQL 13, no extension needed)
- uuid-ossp extension (provides uuid_generate_v1(), uuid_generate_v4(), etc.)
Enable uuid-ossp if needed:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";RFC4122 Compliance:
Some UUID generators (like ULID) create valid 128-bit identifiers but may not strictly follow RFC4122 version bits in the third and fourth blocks. PostgreSQL accepts these as valid UUIDs since they match the format, but be aware of potential compatibility issues with strict RFC4122 validators.
Performance Considerations:
UUID v4 (random) primary keys can cause index fragmentation due to random insertion order. Consider:
- UUID v7 (time-ordered) for better index performance
- Adding sequential integer columns for internal sorting
- Using BIGINT with external UUID generation if insertion performance is critical
Type Casting Bytea:
If you have UUID data stored as bytea, convert it properly:
SELECT encode(bytea_column, 'hex')::uuid FROM table;ORM-Specific Notes:
- Prisma: Use @db.Uuid type mapping
- TypeORM: Use type: 'uuid' with @Generated('uuid')
- Sequelize: Use DataTypes.UUID with defaultValue: DataTypes.UUIDV4
- Django: Use UUIDField with default=uuid.uuid4 (without parentheses)
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL