prestodb/presto · error · PrestoException
SCHEMA_ALREADY_EXISTS
SCHEMA_ALREADY_EXISTS
Error message
Schema '%s' already exists or created by others
What it means
InMemorySchemaStore.insert throws SCHEMA_ALREADY_EXISTS when a schema with the same (lowercased) name is already registered in the in-memory map. The store is a simple synchronized HashMap keyed by lowercase schema name, so duplicate registration is rejected rather than overwritten.
Source
Thrown at presto-lark-sheets/src/main/java/com/facebook/presto/lark/sheets/api/InMemorySchemaStore.java:44
import static java.lang.String.format;
public class InMemorySchemaStore
implements LarkSheetsSchemaStore
{
private final Map<String, LarkSheetsSchema> schemas = new ConcurrentHashMap<>();
@Override
public Optional<LarkSheetsSchema> get(String name)
{
return Optional.ofNullable(schemas.get(lower(name)));
}
@Override
public synchronized void insert(LarkSheetsSchema schema)
{
String name = lower(schema.getName());
if (schemas.containsKey(name)) {
throw new PrestoException(LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS,
format("Schema '%s' already exists or created by others", name));
}
schemas.put(name, schema);
}
@Override
public synchronized void delete(String schemaName)
{
String name = lower(schemaName);
if (!schemas.containsKey(name)) {
throw new PrestoException(LarkSheetsErrorCode.SCHEMA_NOT_EXISTS,
format("Schema '%s' does not exist", name));
}
schemas.remove(name);
}
@Override
public Iterable<LarkSheetsSchema> listForUser(String user)View on GitHub (pinned to 55bb57d202)
Solutions
- Check existence first with a get/list call before inserting, or wrap insert in try-catch for SCHEMA_ALREADY_EXISTS and treat it as a no-op.
- Lowercase the schema name before creating to avoid case-variant duplicates.
- If the connector supports it, use IF NOT EXISTS semantics in CREATE SCHEMA.
Example fix
// before
store.insert(new LarkSheetsSchema("Sales"));
// after
try {
store.insert(new LarkSheetsSchema("sales"));
} catch (PrestoException e) {
if (e.getErrorCode() != LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS.toErrorCodeCode()) {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = store.listForUser(user) != null && streamOf(store.listForUser(user)).anyMatch(s -> s.getName().equalsIgnoreCase(name));
Type guard
boolean schemaExists(InMemorySchemaStore store, String name) { try { store.delete(name); store.insert(new LarkSheetsSchema(name)); return false; } catch (PrestoException e) { return true; } } Try / catch
try { store.insert(schema); } catch (PrestoException e) { if (LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS.toErrorCode().getCode() == e.getErrorCode().getCode()) { /* treat as already-created: continue */ } else { throw e; } } Prevention
- Lowercase schema names before insert/delete to avoid case-variant duplicates.
- Use IF NOT EXISTS / existence checks in provisioning scripts.
- Serialize schema creation through a single coordination point to avoid cross-node races.
When it happens
Trigger: Calling insert(schema) when schemas already contains lower(schema.getName()). Happens on CREATE SCHEMA for a name that already exists, or two nodes/threads concurrently creating the same schema where the second caller loses the race.
Common situations: Re-running an idempotent bootstrap/provisioning script that creates schemas; concurrent CREATE SCHEMA statements racing on different Presto nodes sharing the store; case-insensitive name collision ('Sales' vs 'sales').
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e49fa377347559f2.
Report an issue: GitHub.