quarkusio/quarkus · error · GradleException

Failed to persist extension descriptor

Error message

Failed to persist extension descriptor 

What it means

Thrown by ExtensionDescriptorTask.generateQuarkusExtensionProperties when writing quarkus-extension.properties into META-INF fails with an IOException. The task creates the META-INF directory and stores the resolved Properties object via a BufferedWriter; any I/O problem (missing dir creation, read-only target, closed stream) is wrapped in this GradleException naming the target file.

Source

Thrown at devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ExtensionDescriptorTask.java:314

                        final String resource = resources.get(i);
                        if (!resource.isBlank()) {
                            sb.append(',').append(resource);
                        }
                    }
                    value = sb.toString();
                }
                props.setProperty(ApplicationModelBuilder.REMOVED_RESOURCES_DOT + key, value);
            }
        }

        try {
            Files.createDirectories(metaInfDir);
            try (BufferedWriter writer = Files
                    .newBufferedWriter(metaInfDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME))) {
                props.store(writer, "Generated by extension-descriptor");
            }
        } catch (IOException e) {
            throw new GradleException(
                    "Failed to persist extension descriptor " + metaInfDir.resolve(BootstrapConstants.DESCRIPTOR_FILE_NAME),
                    e);
        }
    }

    private static void setConditionalDepsProperty(String propName, List<String> conditionalDependencies, Properties props) {
        if (conditionalDependencies != null && !conditionalDependencies.isEmpty()) {
            final StringBuilder buf = new StringBuilder();
            int i = 0;
            buf.append(ArtifactCoords.fromString(conditionalDependencies.get(i++)));
            while (i < conditionalDependencies.size()) {
                buf.append(' ').append(ArtifactCoords.fromString(conditionalDependencies.get(i++)));
            }
            props.setProperty(propName, buf.toString());
        }
    }

    private void generateQuarkusExtensionDescriptor(Path outputMetaInfDirectory)

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the task's output directory is writable and not read-only mounted; fix permissions with chmod/chown.
  2. Run gradle clean to remove a partially generated META-INF, then rebuild.
  3. Check disk space and close other processes (IDE sync, previous daemon) holding the descriptor file open.
  4. Run the task alone (avoid concurrent builds writing to the same directory).

Example fix

// before: read-only output dir
extensionDescriptor { outputDirectory = file('/mnt/ro/target/classes') }
// after: point at a writable dir
extensionDescriptor { outputDirectory = file("${buildDir}/classes/java/main") }/
Defensive patterns

Strategy: try-catch

Validate before calling

def out = project.file('build/classes/java/main/META-INF')
if (out.exists() && !out.canWrite()) throw new IllegalStateException("META-INF dir not writable: $out")
if (out.totalSpace > 0 && out.usableSpace < 10L * 1024 * 1024) throw new IllegalStateException('Disk nearly full')

Try / catch

try {
  generateQuarkusExtensionProperties()
} catch (GradleException e) {
  def target = e.message.minus('Failed to persist extension descriptor ')
  new File(target).delete()
  generateQuarkusExtensionProperties() // retry once after removing stale/locked file
}

Prevention

When it happens

Trigger: Files.createDirectories or props.store(writer, ...) throws — e.g. metaInfDir cannot be created under a read-only output directory, the descriptor file is locked by another process, or the disk is full.

Common situations: CI workspaces with the output directory mounted read-only, concurrent tasks writing the same output dir, permission mismatches from switching build users, or full disks.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/c85279018b565dbb. Report an issue: GitHub.