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
- Lowercase the components before constructing: name.toLowerCase(Locale.ENGLISH) on catalog, schema, and object.
- Check the source of the name (config, metastore, user input) and normalize it at ingestion time.
- If the case is meaningful, do not use QualifiedObjectName — use a case-preserving type, since Presto identifiers here must be lowercase.
- 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
- Normalize all identifier components with toLowerCase(Locale.ENGLISH) at system boundaries.
- Store config values already lowercased.
- Remember toLowerCase() can change length for some locales — always use Locale.ENGLISH.
- Add unit tests covering CamelCase inputs.
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
- NOT_SUPPORTED
- dictionarySourceIds must be the same
- blocks is empty
- Column does not have same position count (%s) as page (%s)
- QualifiedObjectName should have exactly 3 parts, found %s: %
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/4f3d40d8366ec9bd.
Report an issue: GitHub.