gradle/gradle · error · InvalidSignatureFileException
Could not read signatures from %s: %s: %s
Error message
Could not read signatures from %s: %s: %s
What it means
SecuritySupport.readSignatures(File) opens a signature file, wraps it in PGPUtil.getDecoderStream (auto-detects ASCII armor and compression), and parses the first PGPSignatureList object. Any IOException or PGPException is rethrown as InvalidSignatureFileException with the message 'Could not read signatures from <file>: <cause class>: <cause message>'. It means the file could not be read as an OpenPGP signature stream.
Source
Thrown at platforms/software/security/src/main/java/org/gradle/security/internal/SecuritySupport.java:88
} catch (IOException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
return signature.verify();
}
private static PGPContentVerifierBuilderProvider createContentVerifier() {
return new BcPGPContentVerifierBuilderProvider();
}
@Nullable
public static PGPSignatureList readSignatures(File file) {
try (
InputStream stream = new BufferedInputStream(Files.newInputStream(file.toPath()));
InputStream decoderStream = PGPUtil.getDecoderStream(stream)
) {
return readSignatureList(decoderStream, file.toString());
} catch (IOException | PGPException e) {
throw new InvalidSignatureFileException(file, e);
}
}
@Nullable
private static PGPSignatureList readSignatureList(InputStream decoderStream, String locationHint) throws IOException, PGPException {
PGPObjectFactory objectFactory = new PGPObjectFactory(decoderStream, new BcKeyFingerprintCalculator());
Object nextObject = objectFactory.nextObject();
if (nextObject instanceof PGPSignatureList) {
return (PGPSignatureList) nextObject;
} else if (nextObject instanceof PGPCompressedData) {
return readSignatureList(((PGPCompressedData) nextObject).getDataStream(), locationHint);
} else {
LOGGER.warn("Expected a signature list in {}, but got {}. Skipping this signature.", locationHint, nextObject == null ? "invalid file" : nextObject.getClass());
return null;
}
}
public static String toLongIdHexString(long key) {View on GitHub (pinned to 534f27719b)
Solutions
- Confirm the file is actually a signature: run gpg --list-packets artifact.asc
- Delete the cached module directory and re-resolve: rm -rf ~/.gradle/caches/modules-2/files-2.1/<group>/<module>
- Re-download the artifact and its signature from a repository that publishes both
- If the module genuinely has no signature, adjust verification metadata (trusted artifacts entry) rather than pointing at a non-signature file
Example fix
# before: build fails with InvalidSignatureFileException on a cached artifact # inspect the offending file gpg --list-packets ~/.gradle/caches/modules-2/files-2.1/my.group/mymodule/*/artifact.jar.asc # clear the corrupt cached module and rebuild rm -rf ~/.gradle/caches/modules-2/files-2.1/my.group/mymodule ./gradlew build --refresh-dependencies
Defensive patterns
Strategy: try-catch
Validate before calling
File asc = new File(artifactPath + ".asc");
if (!asc.exists() || asc.length() == 0) {
throw new IllegalStateException("Signature missing or empty: " + asc);
} Try / catch
try {
PGPSignatureList signatures = SecuritySupport.readSignatures(sigFile);
} catch (InvalidSignatureFileException e) {
// e carries file + root cause; decide: re-download, or record as unverified
log.warn("Unreadable signature {}: {}", sigFile, e.getCause().getMessage());
return VerificationResult.unverified(sigFile, e);
} Prevention
- Check the .asc exists and is non-empty before enabling verification for a module
- Treat partial downloads as poison: verify checksums at download time so caches never hold truncated files
- Keep a scripted cache-clean step (delete the module dir under modules-2/files-2.1) for signature corruption
When it happens
Trigger: Passing the artifact binary instead of its .asc detached signature; a truncated or zero-byte .asc from an interrupted download; a file with broken armor headers (missing BEGIN PGP SIGNATURE); or an I/O error (permissions, disk) while reading.
Common situations: Dependency verification failing on corrupt cached files under ~/.gradle/caches/modules-2; artifacts republished to a mirror without signatures; CI caches containing partial downloads; disk-full leaving half-written .asc files.
Related errors
- Expected a signature list in {}, but got {}. Skipping this s
- A verification file was generated but some problems were dis
- Error while reading the keyring file. {} keys read: {}
- Could not write %s content to %s.
- Could not write %s content to %s.
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/93919342e63b052d.
Report an issue: GitHub.