{"record":{"id":"2df02900995090d7","repo":"spring-projects/spring-ai","slug":"dropping-existing-ttl-index-because-ttl-is-differ","errorCode":null,"errorMessage":"Dropping existing TTL index, because TTL is different","messagePattern":"Dropping existing TTL index, because TTL is different","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/model/chat/memory/repository/mongo/autoconfigure/MongoChatMemoryIndexCreatorAutoConfiguration.java","lineNumber":86,"sourceCode":"\t\tcreateOrUpdateTtlIndex();\n\t}\n\n\tprivate void createMainIndex() {\n\t\tvar indexOps = this.mongoTemplate.indexOps(Conversation.class);\n\t\tvar index = new Index().on(\"conversationId\", Sort.Direction.ASC).on(\"timestamp\", Sort.Direction.DESC);\n\n\t\t// Use reflection to handle API differences across Spring Data MongoDB versions\n\t\tcreateIndexSafely(indexOps, index);\n\t}\n\n\tprivate void createOrUpdateTtlIndex() {\n\t\tif (!this.mongoChatMemoryProperties.getTtl().isZero()) {\n\t\t\tvar indexOps = this.mongoTemplate.indexOps(Conversation.class);\n\t\t\t// Check for existing TTL index\n\t\t\tindexOps.getIndexInfo().forEach(idx -> {\n\t\t\t\tif (idx.getExpireAfter().isPresent()\n\t\t\t\t\t\t&& !idx.getExpireAfter().get().equals(this.mongoChatMemoryProperties.getTtl())) {\n\t\t\t\t\tlogger.warn(\"Dropping existing TTL index, because TTL is different\");\n\t\t\t\t\tindexOps.dropIndex(idx.getName());\n\t\t\t\t}\n\t\t\t});\n\t\t\t// Use reflection to handle API differences across Spring Data MongoDB\n\t\t\t// versions\n\t\t\tcreateIndexSafely(indexOps,\n\t\t\t\t\tnew Index().on(\"timestamp\", Sort.Direction.ASC).expire(this.mongoChatMemoryProperties.getTtl()));\n\t\t}\n\t}\n\n\t/**\n\t * Creates an index using reflection to handle API changes across different Spring\n\t * Data MongoDB versions:\n\t * <ul>\n\t * <li>Spring Data MongoDB 4.2.x - 4.4.x: only {@code ensureIndex(IndexDefinition)} is\n\t * available.</li>\n\t * <li>Spring Data MongoDB 4.5.x+: {@code createIndex(IndexDefinition)} is the new\n\t * API, {@code ensureIndex} is deprecated.</li>","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-mongodb/src/main/java/org/springframework/ai/model/chat/memory/repository/mongo/autoconfigure/MongoChatMemoryIndexCreatorAutoConfiguration.java#L68-L104","documentation":"MongoChatMemoryIndexCreatorAutoConfiguration.createOrUpdateTtlIndex (run from initIndicesAfterStartup) inspects existing indexes on the chat memory Conversation collection and drops any TTL index whose expireAfter value differs from the configured spring.ai.chat.memory.repository.mongodb ttl. This warning fires right before the drop; a new TTL index with the configured value is then created.","triggerScenarios":"Startup with a non-zero configured TTL that does not match the TTL of an existing index on the Conversation collection, e.g. changing spring.ai.chat.memory.repository.mongodb.ttl from 1d to 7d, or an index created by an earlier version/another service with a different expiry.","commonSituations":"Tuning chat-memory retention in an existing deployment; two services sharing one MongoDB database with different TTL settings, causing index drop/recreate flapping on each startup; migration from a schema created manually via mongosh.","solutions":["Align the application's configured ttl with the existing index value if the old retention is intended.","Accept the drop/recreate if changing retention is intentional (note: changing TTL applies to all documents).","Dedicate separate collections/databases per service so differing TTLs do not fight."],"exampleFix":"// before (application.yml)\nspring.ai.chat.memory.repository.mongodb.ttl: 1d\n// after (match existing index TTL of 7d)\nspring.ai.chat.memory.repository.mongodb.ttl: 7d","handlingStrategy":"validation","validationCode":"Duration configured = mongoChatMemoryProperties.getTtl();\nboolean mismatch = mongoTemplate.indexOps(Conversation.class).getIndexInfo().stream()\n    .flatMap(i -> i.getExpireAfter().stream())\n    .anyMatch(exp -> !exp.equals(configured));\nif (mismatch) {\n    // index will be dropped and recreated; confirm retention change is intentional\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check existing TTL indexes (db.conversation.getIndexes()) before changing the ttl property.","Avoid multiple services sharing a collection with different TTLs.","Treat TTL changes as schema migrations with review."],"tags":["mongodb","ttl-index","chat-memory","spring-boot","index-management"],"backgroundTag":"ttl-index-mismatch","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}