alibaba/nacos · error · FileNotFoundException

{getDescription()} cannot be resolved to URL because it does

Error message

{getDescription()} cannot be resolved to URL because it does not exist

What it means

ClassPathResource.getUrl() resolves a URL for the resource the same way getInputStream does, but for the URL representation. If no loader can produce a URL (resource absent or not addressable), it throws FileNotFoundException with this description. It is the URL analogue of error 762.

Source

Thrown at common/src/main/java/com/alibaba/nacos/common/packagescan/resource/ClassPathResource.java:215

        }
        if (is == null) {
            throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
        }
        return is;
    }

    /**
     * This implementation returns a URL for the underlying class path resource,
     * if available.
     *
     * @see ClassLoader#getResource(String)
     * @see Class#getResource(String)
     */
    @Override
    public URL getUrl() throws IOException {
        URL url = resolveUrl();
        if (url == null) {
            throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
        }
        return url;
    }

    /**
     * This implementation creates a ClassPathResource, applying the given path
     * relative to the path of the underlying resource of this descriptor.
     *
     * @see StringUtils#applyRelativePath(String, String)
     */
    @Override
    public Resource createRelative(String relativePath) {
        String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
        return (this.clazz != null ? new ClassPathResource(pathToUse, this.clazz) :
                new ClassPathResource(pathToUse, this.classLoader));
    }

    /**

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Confirm the resource exists on the classpath (see 762 diagnostics).
  2. If you only need the bytes, prefer getInputStream() over getUrl() to avoid URL-layout limitations in nested/fat jars.
  3. For nested-jar URL needs, use a loader designed for that layout (e.g. the app's resource loader) instead of the raw ClassPathResource URL path.

Example fix

// before — URL unavailable for an absent or nested resource
URL u = new ClassPathResource("config/app.yml").getUrl(); // throws

// after — read bytes directly via stream
try (InputStream in = new ClassPathResource("config/app.yml").getInputStream()) { ... }
Defensive patterns

Strategy: validation

Validate before calling

static URL urlIfExists(ClassPathResource r) throws IOException {
    URL u = r.getUrl(); // will still throw; guard with exists()
    return u;
}
// Prefer:
static URL safeUrl(ClassPathResource r) throws IOException {
    if (!r.exists()) throw new FileNotFoundException("not on classpath: " + r.getPath());
    return r.getUrl();
}

Try / catch

try {
    URL u = resource.getUrl();
} catch (FileNotFoundException fnf) {
    // resolve via getInputStream() instead, or fail fast
}

Prevention

When it happens

Trigger: Calling getUrl() (or any code path that needs a URL, e.g. logging the resource location) on a ClassPathResource whose resolveUrl() returned null. Same root causes as 762 but triggered through the URL resolution path.

Common situations: Same as 762: missing file in JAR, wrong path, wrong leading slash, fat-jar relocation. Additionally, resources inside certain nested JAR layouts (Spring Boot nested jars) can be InputStream-resolvable but not URL-resolvable by a plain classloader.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/c5468d42f1122bbe. Report an issue: GitHub.