prestodb/presto · error · java.lang.IllegalArgumentException

%s is not lowercase: %s

Error message

%s is not lowercase: %s

What it means

QualifiedObjectName requires its catalog, schema, and object name parts to be lowercase. checkLowerCase throws this IllegalArgumentException when any component contains uppercase (or any character that changes under toLowerCase(ENGLISH)), enforcing Presto's lowercase identifier convention for qualified object names.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/QualifiedObjectName.java:132

    @Override
    public int hashCode()
    {
        return Objects.hash(catalogName, schemaName, objectName);
    }

    @JsonValue
    @Override
    public String toString()
    {
        return catalogName + '.' + schemaName + '.' + objectName;
    }

    private static void checkLowerCase(String value, String name)
    {
        requireNonNull(value, format("%s is null", name));
        if (!value.equals(value.toLowerCase(ENGLISH))) {
            throw new IllegalArgumentException(format("%s is not lowercase: %s", name, value));
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Lowercase the components before constructing: name.toLowerCase(Locale.ENGLISH) on catalog, schema, and object.
  2. Check the source of the name (config, metastore, user input) and normalize it at ingestion time.
  3. If the case is meaningful, do not use QualifiedObjectName — use a case-preserving type, since Presto identifiers here must be lowercase.
  4. Update stored configuration to already-lowercase values rather than lowercasing at every use site.

Example fix

// before
QualifiedObjectName name = new QualifiedObjectName("Hive", "default", "MyTable"); // throws
// after
QualifiedObjectName name = new QualifiedObjectName(
    catalog.toLowerCase(Locale.ENGLISH),
    schema.toLowerCase(Locale.ENGLISH),
    table.toLowerCase(Locale.ENGLISH));
Defensive patterns

Strategy: validation

Validate before calling

String catalog = "Hive".toLowerCase(Locale.ENGLISH);
String schema = "Default".toLowerCase(Locale.ENGLISH);
String table = "MyTable".toLowerCase(Locale.ENGLISH);
QualifiedObjectName name = new QualifiedObjectName(catalog, schema, table);

Type guard

boolean isLowerCase(String s) {
    return s != null && s.equals(s.toLowerCase(Locale.ENGLISH));
}

Try / catch

try {
    QualifiedObjectName name = QualifiedObjectName.valueOf(raw);
} catch (IllegalArgumentException e) {
    // normalize case and retry once
    QualifiedObjectName name = QualifiedObjectName.valueOf(raw.toLowerCase(Locale.ENGLISH));
}

Prevention

When it happens

Trigger: Constructing a QualifiedObjectName (via constructor or valueOf) with a part like "Hive", "DEFAULT", or "MyTable" that is not entirely lowercase.

Common situations: Names read from OS paths, config files, or case-sensitive external systems (e.g. S3 bucket keys, Hive metastore with case-preserving catalogs); older configs written before a lowercase-enforcement change; users typing CamelCase table names.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/4f3d40d8366ec9bd. Report an issue: GitHub.