spring-projects/spring-boot · error · GradleException

Each image building cache can be configured only once

Error message

Each image building cache can be configured only once

What it means

Thrown by CacheSpec.volume when this.cache is already non-null, meaning a cache configuration method (volume, bind, or image) has already been called on this CacheSpec. Each CacheSpec can configure exactly one cache type; calling a second method throws. This is the volume() entry point — the first of the three mutually exclusive cache configurators.

Solutions

  1. Keep only one cache configuration block (volume, bind, or image) per CacheSpec in your bootBuildImage configuration.
  2. Audit the build script for duplicate cache { volume/bind/image } calls and remove all but one.
  3. If you need different caches for different purposes, they must be on separate CacheSpec instances (e.g. different builder phases), not the same one.

Example fix

// before
tasks.bootBuildImage {
    cache {
        volume { name = "my-cache" }
        bind { source = "/tmp/cache" }  // throws
    }
}
// after
tasks.bootBuildImage {
    cache {
        bind { source = "/tmp/cache" }
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Track cache configuration count in your build script and assert uniqueness.
def cacheTypes = []
tasks.bootBuildImage {
    cache {
        // only call ONE of: volume {}, bind {}, image {}
        if (cacheTypes) throw new GradleException("Cache already configured: " + cacheTypes)
        cacheTypes << 'volume'
        volume { name = "my-cache" }
    }
}

Prevention

When it happens

Trigger: Calling cache.volume { } after already calling cache.volume { }, cache.bind { }, or cache.image { } on the same CacheSpec instance within a bootBuildImage task configuration block.

Common situations: Copy-pasting DSL blocks that each configure a different cache type. Migrating from a volume cache to a bind cache and forgetting to remove the old block. Misunderstanding that only one cache type is allowed per CacheSpec.

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/fadfe1925ed17157. Report an issue: GitHub.

Appendix: source

Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/CacheSpec.java:59

	private @Nullable Cache cache;

	@Inject
	public CacheSpec(ObjectFactory objectFactory) {
		this.objectFactory = objectFactory;
	}

	public @Nullable Cache asCache() {
		return this.cache;
	}

	/**
	 * Configures a volume cache using the given {@code action}.
	 * @param action the action
	 */
	public void volume(Action<VolumeCacheSpec> action) {
		if (this.cache != null) {
			throw new GradleException("Each image building cache can be configured only once");
		}
		VolumeCacheSpec spec = this.objectFactory.newInstance(VolumeCacheSpec.class);
		action.execute(spec);
		this.cache = Cache.volume(spec.getName().get());
	}

	/**
	 * Configures a bind cache using the given {@code action}.
	 * @param action the action
	 */
	public void bind(Action<BindCacheSpec> action) {
		if (this.cache != null) {
			throw new GradleException("Each image building cache can be configured only once");
		}
		BindCacheSpec spec = this.objectFactory.newInstance(BindCacheSpec.class);
		action.execute(spec);
		this.cache = Cache.bind(spec.getSource().get());
	}

View on GitHub (pinned to 270dfe353f)