apache/seatunnel · error · EasysearchConnectorException
CREATE_INDEX_FAILED
CREATE_INDEX_FAILED
Error message
PUT ${endpoint} response status code=%d What it means
createIndex PUTs /{indexName} and throws CREATE_INDEX_FAILED with the HTTP status code when the response status is not 200 (note: Elasticsearch also returns 200 for successful creation, so any other code means rejection). Typical causes are a 400 (invalid index name) or 400 'resource_already_exists_exception' when the index already exists.
Source
Thrown at seatunnel-connectors-v2/connector-easysearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/easysearch/client/EasysearchClient.java:523
EasysearchConnectorErrorCode.LIST_INDEX_FAILED,
String.format(
"GET %s response status code=%d",
endpoint, response.getStatusLine().getStatusCode()));
}
} catch (IOException ex) {
throw new EasysearchConnectorException(
EasysearchConnectorErrorCode.LIST_INDEX_FAILED, ex);
}
}
// todo: We don't support set the index mapping now.
public void createIndex(String indexName) {
String endpoint = String.format("/%s", indexName);
Request request = new Request("PUT", endpoint);
try {
Response response = restClient.performRequest(request);
if (response == null) {
throw new EasysearchConnectorException(
EasysearchConnectorErrorCode.CREATE_INDEX_FAILED,
"PUT " + endpoint + " response null");
}
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new EasysearchConnectorException(
EasysearchConnectorErrorCode.CREATE_INDEX_FAILED,
String.format(
"PUT %s response status code=%d",
endpoint, response.getStatusLine().getStatusCode()));
}
} catch (IOException ex) {
throw new EasysearchConnectorException(
EasysearchConnectorErrorCode.CREATE_INDEX_FAILED, ex);
}
}
public void dropIndex(String tableName) {
String endpoint = String.format("/%s", tableName);View on GitHub (pinned to cf67b549a7)
Solutions
- Lowercase the index name and strip illegal characters before createIndex
- Treat 'resource_already_exists_exception' (400) as success/idempotent — check existence first with a HEAD request or catch and ignore
- Grant the user cluster 'create_index' and index 'manage' privileges
- Check the status code: 400 name/validation issue, 403 authz issue, 5xx server issue
Example fix
// before
createIndex(tableName); // tableName = "MyTable"
// after
String idx = tableName.toLowerCase().replaceAll("[\\s/?:\"<>|,#]", "_");
if (!indexExists(idx)) createIndex(idx); Defensive patterns
Strategy: try-catch
Validate before calling
String idx = indexName.toLowerCase();
if (!idx.matches("[a-z0-9][a-z0-9_.-]*") || idx.length() > 255) throw new IllegalArgumentException("invalid index name: " + indexName);
try { restClient.performRequest(new Request("HEAD", "/" + idx)); exists = true; } catch (ResponseException e) { exists = false; } Try / catch
try { client.createIndex(index); } catch (EasysearchConnectorException e) { if (e.getMessage().contains("resource_already_exists") || e.getMessage().contains("400")) { log.info("index exists, continuing"); } else throw e; } Prevention
- Normalize table names to lowercase, no illegal chars, ≤255 bytes
- Make index creation idempotent (check existence or tolerate already-exists 400)
- Grant create_index/manage privileges to the job user
- Avoid parallel tasks racing to create the same index
When it happens
Trigger: Auto-create-index before writing: PUT /{index} rejected with 400 invalid index name (uppercase, invalid chars, too long), 400 index already exists, or 403 insufficient permissions.
Common situations: Table name derived from upstream data contains characters illegal for index names (uppercase, '\/', '?', '"', '<', '>', '|', ' ', ',', '#'), race between parallel tasks creating the same index, user lacking 'create_index' privilege.
Related errors
- SCROLL_REQUEST_ERROR
- GET_INDEX_DOCS_COUNT_FAILED
- LIST_INDEX_FAILED
- REQUEST_FAILED
- Request failed with code:{}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/8726a56cfbe4390f.
Report an issue: GitHub.