apache/seatunnel · error · CatalogException

Failed to create collection

Error message

Failed to create collection: ${tablePath.getFullName()}

What it means

After the existence checks pass, createTable calls db.createCollection(...); any driver/server failure is wrapped in a CatalogException "Failed to create collection: <fullName>". The wrapped cause carries the actual MongoDB error.

Solutions

  1. Inspect e.getCause() for the Mongo error code (e.g., NamespaceExists means a race with another creator).
  2. Treat Mongo error code 48 (NamespaceExists) as benign if ignoreIfExists semantics are desired — retry with existence check.
  3. Sanitize the table name to meet MongoDB collection naming rules.
  4. Grant the user createCollection privilege on the database.
  5. Serialize creation (single writer) or use createCollection with ignore-duplicate handling.

Example fix

// before
db.createCollection(tableName);
// after
try {
    db.createCollection(tableName);
} catch (MongoCommandException e) {
    if (e.getErrorCode() != 48) throw e; // 48 = NamespaceExists
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate name against MongoDB rules
if (tableName.contains("\u0000") || tableName.length() > 255) {
    throw new IllegalArgumentException("bad collection name");
}

Try / catch

try {
    catalog.createTable(tablePath, table, true);
} catch (CatalogException e) {
    if (e.getCause() instanceof MongoCommandException
        && ((MongoCommandException) e.getCause()).getErrorCode() == 48) {
        // namespace exists: benign race
    } else { throw e; }
}

Prevention

When it happens

Trigger: Collection created by a concurrent writer between the tableExists check and createCollection (race), invalid collection name (e.g., contains null char or exceeds length limits), insufficient createCollection privileges, or connection loss.

Common situations: Concurrent jobs racing to create the same collection, restricted user lacking createCollection action, collection names with forbidden characters derived from table paths, server hitting namespace limits.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/db36125a395b6fa5. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-mongodb/src/main/java/org/apache/seatunnel/connectors/seatunnel/mongodb/catalog/MongodbCatalog.java:139

            throws CatalogException, TableNotExistException {
        throw CommonError.unsupportedOperation(name(), "get table with tablePath ");
    }

    @Override
    public void createTable(TablePath tablePath, CatalogTable table, boolean ignoreIfExists)
            throws TableAlreadyExistException, DatabaseNotExistException, CatalogException {
        if (!databaseExists(tablePath.getDatabaseName())) {
            throw new DatabaseNotExistException(name(), tablePath.getDatabaseName());
        }
        if (tableExists(tablePath)) {
            if (ignoreIfExists) return;
            throw new TableAlreadyExistException(name(), tablePath);
        }
        try {
            MongoDatabase db = mongoClient.getDatabase(tablePath.getDatabaseName());
            db.createCollection(tablePath.getTableName());
        } catch (Exception e) {
            throw new CatalogException(
                    "Failed to create collection: " + tablePath.getFullName(), e);
        }
    }

    @Override
    public void dropTable(TablePath tablePath, boolean ignoreIfNotExists)
            throws TableNotExistException, CatalogException {
        if (!tableExists(tablePath)) {
            if (ignoreIfNotExists) return;
            throw new TableNotExistException(name(), tablePath);
        }
        try {
            MongoDatabase db = mongoClient.getDatabase(tablePath.getDatabaseName());
            db.getCollection(tablePath.getTableName()).drop();
        } catch (Exception e) {
            throw new CatalogException("Failed to drop collection: " + tablePath.getFullName(), e);
        }
    }

View on GitHub (pinned to cf67b549a7)