jackc/pgx · error

authentication message too short

Error message

authentication message too short

What it means

Returned by Frontend.findAuthenticationMessageType when the 'R' (Authentication) message body is shorter than 4 bytes. The first 4 bytes of an authentication message carry the auth-type code that selects the concrete sub-message, so fewer than 4 bytes cannot even be dispatched. This indicates a truncated or corrupt message from the server.

Source

Thrown at pgproto3/frontend.go:427

// Authentication message type constants.
// See src/include/libpq/pqcomm.h for all
// constants.
const (
	AuthTypeOk                = 0
	AuthTypeCleartextPassword = 3
	AuthTypeMD5Password       = 5
	AuthTypeSCMCreds          = 6
	AuthTypeGSS               = 7
	AuthTypeGSSCont           = 8
	AuthTypeSSPI              = 9
	AuthTypeSASL              = 10
	AuthTypeSASLContinue      = 11
	AuthTypeSASLFinal         = 12
)

func (f *Frontend) findAuthenticationMessageType(src []byte) (BackendMessage, error) {
	if len(src) < 4 {
		return nil, errors.New("authentication message too short")
	}
	f.authType = binary.BigEndian.Uint32(src[:4])

	switch f.authType {
	case AuthTypeOk:
		return &f.authenticationOk, nil
	case AuthTypeCleartextPassword:
		return &f.authenticationCleartextPassword, nil
	case AuthTypeMD5Password:
		return &f.authenticationMD5Password, nil
	case AuthTypeSCMCreds:
		return nil, errors.New("AuthTypeSCMCreds is unimplemented")
	case AuthTypeGSS:
		return &f.authenticationGSS, nil
	case AuthTypeGSSCont:
		return &f.authenticationGSSContinue, nil
	case AuthTypeSSPI:
		return nil, errors.New("AuthTypeSSPI is unimplemented")

View on GitHub (pinned to ec1a0befd2)

Solutions

  1. Verify you are connecting to a real PostgreSQL server on the correct host/port (check for a mispointed service or a load balancer returning an HTTP error page).
  2. If a proxy is in the path, ensure it forwards Authentication messages without truncation.
  3. Log the full message length and type byte to confirm the framing is correct; a length < 4 on an 'R' message is almost always upstream corruption.
  4. Reconnect; transient corruption may clear. If it persists, capture a packet trace to locate where bytes are dropped.

Example fix

// before
cfg, _ := pgx.ParseConfig("host=db port=5432")
conn, err := pgx.ConnectConfig(ctx, cfg) // server/proxy sent a truncated 'R' message

// after
cfg, _ := pgx.ParseConfig("host=db port=5432")
cfg.Tracer = tracelog.NewLoggerTracer(logger) // surface the exact message that fails
conn, err := pgx.ConnectConfig(ctx, cfg)
if err != nil {
    log.Printf("auth handshake failed (is %s:%d really postgres?): %v", cfg.Host, cfg.Port, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

conn, err := pgx.Connect(ctx, connString)
if err != nil {
    if strings.Contains(err.Error(), "authentication message too short") {
        // server/proxy sent a truncated 'R' message — likely wrong endpoint or corrupted stream
        log.Printf("auth handshake corrupt: %v. Verify %s is a real PostgreSQL server.", err, connString)
    }
    return err
}

Prevention

When it happens

Trigger: Frontend.Receive reads an 'R'-typed message whose declared body length is less than 4 bytes, then findAuthenticationMessageType rejects it. Hit during the connection authentication handshake when the server (or a proxy in between) sends a malformed Authentication message.

Common situations: A buggy proxy or a man-in-the-middle truncates the auth message. A non-PostgreSQL server (or a port pointed at the wrong service) returns bytes that happen to parse as an 'R' type but with no payload. Connection corruption or a half-closed socket can also produce this.

Related errors


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /data/errors/97c6f77818857601.json. Report an issue: GitHub.