spring-projects/spring-boot · error · ReportableException

Could not save the project, the server did not set a preferr

Error message

Could not save the project, the server did not set a preferred file name and no location was set. Specify the output location for the project.

What it means

Thrown by ProjectGenerator.generateProject when the project was generated as a non-extractable response (or extraction was skipped) and the resolved file name is null - i.e. neither the user supplied --output nor the server returned a preferred file name via Content-Disposition. With no target path the bytes cannot be written anywhere.

Source

Thrown at cli/spring-boot-cli/src/main/java/org/springframework/boot/cli/command/init/ProjectGenerator.java:63

		this.initializrService = initializrService;
	}

	void generateProject(ProjectGenerationRequest request, boolean force) throws IOException {
		ProjectGenerationResponse response = this.initializrService.generate(request);
		String fileName = (request.getOutput() != null) ? request.getOutput() : response.getFileName();
		if (shouldExtract(request, response)) {
			if (isZipArchive(response)) {
				extractProject(response, request.getOutput(), force);
				return;
			}
			else {
				Log.info("Could not extract '" + response.getContentType() + "'");
				// Use value from the server since we can't extract it
				fileName = response.getFileName();
			}
		}
		if (fileName == null) {
			throw new ReportableException("Could not save the project, the server did not set a preferred "
					+ "file name and no location was set. Specify the output location for the project.");
		}
		writeProject(response, fileName, force);
	}

	/**
	 * Detect if the project should be extracted.
	 * @param request the generation request
	 * @param response the generation response
	 * @return if the project should be extracted
	 */
	private boolean shouldExtract(ProjectGenerationRequest request, ProjectGenerationResponse response) {
		if (request.isExtract()) {
			return true;
		}
		// explicit name hasn't been provided for an archive and there is no extension
		return isZipArchive(response) && request.getOutput() != null && !request.getOutput().contains(".");
	}

View on GitHub (pinned to 5b2dbdbb8b)

Solutions

  1. Pass an explicit output location: `spring init --output myapp.zip` (or `myapp/` to extract).
  2. If you control the service, ensure it sets Content-Disposition with a filename for non-zip or non-extracted responses.
  3. If extraction is intended, ensure the response Content-Type is application/zip so shouldExtract() returns true and extraction writes under the output directory.

Example fix

// before
$ spring init myapp   # server returned no filename
// after
$ spring init --output myapp.zip myapp
Defensive patterns

Strategy: validation

Validate before calling

String out = request.getOutput();
boolean serverNamesFile = (response != null && response.getFileName() != null);
if (out == null && !serverNamesFile) {
    throw new IllegalStateException("No output location and server provided no filename; set --output.");
}

Type guard

boolean canPersist = request.getOutput() != null
    || (response != null && response.getFileName() != null);

Try / catch

// Not recommended: the CLI is the caller here. Instead validate pre-call.
// If embedding ProjectGenerator:
try { generator.generateProject(request, force); }
catch (ReportableException ex) {
    if (ex.getMessage().startsWith("Could not save the project")) {
        request.setOutput("project.zip");
        generator.generateProject(request, force);
    } else throw ex;
}

Prevention

When it happens

Trigger: Calling `spring init` without --output, when the Initializr response carries no 'fileName' (ProjectGenerationResponse.getFileName() returns null) and the response is not a zip being extracted. Line 50 falls through and line 62 sees fileName == null.

Common situations: Custom Initializr that omits the Content-Disposition header; response content type isn't application/zip so extraction isn't attempted; a proxy stripping headers; an older/newer service version that changed its header behavior.

Related errors


AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04). Data as JSON: /data/errors/abb02e3dca28e29c.json. Report an issue: GitHub.