hibernate/hibernate-orm · error · IllegalArgumentException

Unknown type nullability code [${code}] encountered

Error message

Unknown type nullability code [${code}] encountered

What it means

TypeNullability.interpret(short) maps the NULLABLE column of DatabaseMetaData.getTypeInfo() onto an enum, accepting only the three JDBC constants: typeNoNulls (0), typeNullable (1), and typeNullableUnknown (2). Any other short value throws IllegalArgumentException. It fires when JDBC metadata supplied by the driver contains a nullability code outside the standard, i.e. a driver that does not conform to the JDBC spec.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/spi/TypeNullability.java:44

	 * It is unknown if the data type accepts nulls
	 * @see DatabaseMetaData#typeNullableUnknown
	 */
	UNKNOWN;

	/**
	 * Based on the code retrieved from {@link DatabaseMetaData#getTypeInfo()} for the {@code NULLABLE}
	 * column, return the appropriate enum.
	 *
	 * @param code The retrieved code value.
	 *
	 * @return The corresponding enum.
	 */
	public static TypeNullability interpret(short code) {
		return switch (code) {
			case DatabaseMetaData.typeNullable -> NULLABLE;
			case DatabaseMetaData.typeNoNulls -> NON_NULLABLE;
			case DatabaseMetaData.typeNullableUnknown -> UNKNOWN;
			default -> throw new IllegalArgumentException( "Unknown type nullability code [" + code + "] encountered" );
		};
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Print the raw NULLABLE values from DriverManager-based getTypeInfo() to confirm which code the driver emits
  2. Upgrade or replace the JDBC driver with a spec-conformant build
  3. If you own the calling code, guard unknown codes yourself and fall back to UNKNOWN instead of calling interpret blindly
  4. Report the nonstandard code to the driver vendor

Example fix

// before
short code = rs.getShort("NULLABLE");
TypeNullability tn = TypeNullability.interpret(code); // throws for unknown codes

// after
short code = rs.getShort("NULLABLE");
TypeNullability tn = switch (code) {
    case DatabaseMetaData.typeNoNulls -> TypeNullability.NON_NULLABLE;
    case DatabaseMetaData.typeNullable -> TypeNullability.NULLABLE;
    case DatabaseMetaData.typeNullableUnknown -> TypeNullability.UNKNOWN;
    default -> TypeNullability.UNKNOWN; // tolerate nonstandard driver codes
};
Defensive patterns

Strategy: validation

Validate before calling

static java.util.Optional<TypeNullability> tryInterpret(short code) {
    return switch (code) {
        case DatabaseMetaData.typeNoNulls -> java.util.Optional.of(TypeNullability.NON_NULLABLE);
        case DatabaseMetaData.typeNullable -> java.util.Optional.of(TypeNullability.NULLABLE);
        case DatabaseMetaData.typeNullableUnknown -> java.util.Optional.of(TypeNullability.UNKNOWN);
        default -> java.util.Optional.empty();        // nonstandard driver code: skip
    };
}

Try / catch

try {
    nullability = TypeNullability.interpret(code);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("nullability code")) {
        nullability = TypeNullability.UNKNOWN;       // degrade instead of aborting metadata scans
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling TypeNullability.interpret(code) with a raw value read from the NULLABLE column of getTypeInfo(); drivers that return vendor-specific codes, garbage, or derived values instead of 0/1/2; metadata-extraction or reverse-engineering tools that iterate getTypeInfo() results and feed them to this interpreter.

Common situations: Exotic or legacy JDBC drivers (ODBC bridge, old Informix/Progress/OpenEdge builds, minimal community drivers) whose getTypeInfo() output deviates from the spec; database upgrades where the driver version changed metadata behavior; custom tooling scanning database type metadata.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/6e2cec9e6ceafd9d. Report an issue: GitHub.