xkcoding/spring-boot-demo · error · ElasticsearchException

创建索引 {index} 失败

Error message

创建索引 {index} 失败

What it means

Thrown by createIndexRequest when RestHighLevelClient.indices().create() raises an IOException — the underlying HTTP call to the Elasticsearch cluster failed at the transport layer. The catch wraps only IOException, so any RuntimeException (e.g. ElasticsearchStatusException for a pre-existing index or invalid settings) propagates uncaught. The original exception `e` is also discarded (not passed as cause), so the root cause stack trace is lost.

Source

Thrown at demo-elasticsearch-rest-high-level-client/src/main/java/com/xkcoding/elasticsearch/service/base/BaseElasticsearchService.java:69

    /**
     * create elasticsearch index (asyc)
     *
     * @param index elasticsearch index
     * @author fxbin
     */
    protected void createIndexRequest(String index) {
        try {
            CreateIndexRequest request = new CreateIndexRequest(index);
            // Settings for this index
            request.settings(Settings.builder().put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards()).put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas()));

            CreateIndexResponse createIndexResponse = client.indices().create(request, COMMON_OPTIONS);

            log.info(" whether all of the nodes have acknowledged the request : {}", createIndexResponse.isAcknowledged());
            log.info(" Indicates whether the requisite number of shard copies were started for each shard in the index before timing out :{}", createIndexResponse.isShardsAcknowledged());
        } catch (IOException e) {
            throw new ElasticsearchException("创建索引 {" + index + "} 失败");
        }
    }

    /**
     * delete elasticsearch index
     *
     * @param index elasticsearch index name
     * @author fxbin
     */
    protected void deleteIndexRequest(String index) {
        DeleteIndexRequest deleteIndexRequest = buildDeleteIndexRequest(index);
        try {
            client.indices().delete(deleteIndexRequest, COMMON_OPTIONS);
        } catch (IOException e) {
            throw new ElasticsearchException("删除索引 {" + index + "} 失败");
        }
    }

View on GitHub (pinned to 87a142f960)

Solutions

  1. Verify the cluster is reachable: curl the cluster node URL (schema://host:9200) and confirm a 200 response.
  2. Check application.yml: demo.data.elasticsearch.clusterNodes must list correct host:port entries; set account.username/password if x-pack security is on.
  3. Pass the caught exception as the cause so the real error surfaces: new ElasticsearchException("...", e).
  4. Widen the catch to include RuntimeException or ElasticsearchStatusException to handle ES-level errors (index already exists) gracefully.

Example fix

// before
} catch (IOException e) {
    throw new ElasticsearchException("创建索引 {" + index + "} 失败");
}

// after
} catch (IOException e) {
    throw new ElasticsearchException("创建索引 {" + index + "} 失败", e);
} catch (ElasticsearchStatusException e) {
    throw new ElasticsearchException("创建索引 {" + index + "} 失败: " + e.getDetailedMessage(), e);
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify cluster connectivity before creating an index
boolean reachable = false;
try {
    org.elasticsearch.client.indices.GetIndexRequest existsReq =
        new org.elasticsearch.client.indices.GetIndexRequest(index);
    boolean exists = client.indices().exists(existsReq, COMMON_OPTIONS);
    if (exists) {
        // index already exists — skip creation or handle accordingly
        return;
    }
    reachable = true;
} catch (IOException e) {
    log.error("ES cluster unreachable before createIndex", e);
}
if (!reachable) return;

Try / catch

try {
    createIndexRequest(index);
} catch (ElasticsearchException e) {
    // ElasticsearchException is a RuntimeException — inspect e.getMessage() for the index name
    log.error("Index creation failed for {}: {}", index, e.getMessage());
    throw e; // or handle with fallback
}

Prevention

When it happens

Trigger: Calling createIndexRequest(indexName) when the ES cluster is unreachable (wrong host/port in demo.data.elasticsearch.clusterNodes), network partition, connect/socket timeout (default 1000ms/30000ms), or when the clusterNode list is empty. Also triggered by auth misconfiguration when security is enabled on the cluster but account credentials are unset.

Common situations: Elasticsearch cluster not started or on a different host than configured; firewall blocking ports 9200/9300; x-pack security enabled but username/password properties left null; RestClient connection pool exhausted (maxConnectTotal=30).

Related errors


AI-assisted analysis of xkcoding/spring-boot-demo@87a142f960 (2026-08-14). Data as JSON: /api/errors/ec79961ba58aa1b6. Report an issue: GitHub.