{"record":{"id":"3dfbac177f0fed4e","repo":"apache/druid","slug":"could-not-find-match-for-pattern-s-in-s-for","errorCode":null,"errorMessage":"Could not find match for pattern `%s` in [%s] for %s","messagePattern":"Could not find match for pattern `(.+?)` in \\[(.+?)\\] for (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":404,"severity":"error","filePath":"extensions-core/lookups-cached-global/src/main/java/org/apache/druid/server/lookup/namespace/UriCacheGenerator.java","lineNumber":108,"sourceCode":"      );\n    }\n    final URIDataPuller puller = (URIDataPuller) pullerRaw;\n    final URI uri;\n    if (doSearch) {\n      final Pattern versionRegex;\n\n      if (extractionNamespace.getFileRegex() != null) {\n        versionRegex = Pattern.compile(extractionNamespace.getFileRegex());\n      } else {\n        versionRegex = null;\n      }\n      uri = pullerRaw.getLatestVersion(\n          extractionNamespace.getUriPrefix(),\n          versionRegex\n      );\n\n      if (uri == null) {\n        throw new FileNotFoundException(\n            StringUtils.format(\n                \"Could not find match for pattern `%s` in [%s] for %s\",\n                versionRegex,\n                originalUri,\n                extractionNamespace\n            )\n        );\n      }\n    } else {\n      uri = extractionNamespace.getUri();\n    }\n\n    return RetryUtils.retry(\n        () -> {\n          final String version = puller.getVersion(uri);\n          try {\n            // Important to call equals() against version because lastVersion could be null\n            if (version.equals(lastVersion)) {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/lookups-cached-global/src/main/java/org/apache/druid/server/lookup/namespace/UriCacheGenerator.java#L90-L126","documentation":"When a uriPrefix is configured, UriCacheGenerator asks the puller for the latest version matching the configured regex pattern via getLatestVersion(). If no URI in the prefix directory matches the pattern, it throws a FileNotFoundException with this message, naming the regex, prefix URI, and namespace.","triggerScenarios":"generateCache() with extractionNamespace.getUriPrefix() != null where puller.getLatestVersion(prefix, versionRegex) returns null — no file/object under the prefix matches the regex.","commonSituations":"Regex too restrictive (e.g. pattern expects a date format the files don't use); files not yet uploaded to the remote location; wrong path/prefix; permissions hide the objects from listing.","solutions":["Fix the versionRegex so it matches the actual file names under the prefix (test with a regex tool).","Verify files exist at the configured uriPrefix location.","Correct the uriPrefix path and confirm list permissions for the storage backend."],"exampleFix":"// before\n\"versionRegex\": \"lookup_v\\\\d{8}\\\\.json\"  // files are lookup_v1.json\n// after\n\"versionRegex\": \"lookup_v\\\\d+\\\\.json\"","handlingStrategy":"validation","validationCode":"Pattern p = Pattern.compile(versionRegex);\nboolean matches = listObjects(uriPrefix).stream().anyMatch(u -> p.matcher(u.toString()).find());\nif (!matches) throw new IllegalStateException(\"versionRegex matches nothing under \" + uriPrefix);","typeGuard":null,"tryCatchPattern":"try { scheduler.schedule(uriNamespace); } catch (FileNotFoundException e) { if (e.getMessage().startsWith(\"Could not find match for pattern\")) { /* fix regex or upload data */ } else { throw e; } }","preventionTips":["Test versionRegex against real file names before deploying","Verify objects exist and are listable at the prefix","Keep regex permissive enough for current naming scheme"],"tags":["file-not-found","regex","lookup"],"backgroundTag":"file-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}