apereo/cas · warning
Unable to pull changes from the remote repository. Metadata…
Error message
Unable to pull changes from the remote repository. Metadata files may be stale.
What it means
WARN log emitted by GitSamlRegisteredServiceMetadataResolver.load when gitRepository.pull() returns false while refreshing the metadata Git repository. The resolver proceeds to list XML metadata files from the local clone, so results reflect the last successfully pulled state. It exists so operators notice that SP metadata loaded from Git may be outdated.
Solutions
- Run a manual git pull in the configured metadata directory to expose the real error (auth, DNS, conflict).
- Fix remote credentials or URL in cas.authn.saml.* metadata git settings.
- Clean the local clone (git reset --hard; remove conflicting edits) so subsequent pulls succeed.
- Verify the resolver is scheduled/refreshed once connectivity is restored so stale entries are replaced.
- Consider alerts on this log since it silently degrades to stale metadata.
Example fix
// before: stale clone left after failed pull $ cd /etc/cas/saml-metadata && git pull error: Your local changes would be overwritten by merge // after $ git reset --hard origin/main && git clean -fd && git pull Already up to date.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight check before relying on the resolver
var dir = new File(metadataRepoDirectory);
if (!new File(dir, ".git").exists()) {
throw new IllegalStateException("Metadata directory is not a git clone: " + dir);
} Try / catch
try {
List<SamlMetadataDocument> docs = resolver.load();
} catch (Exception e) {
LOGGER.error("Metadata load failed entirely; serving cached/previous docs", e);
} Prevention
- Periodically fetch the remote manually to detect auth or connectivity drift
- Alert on 'Unable to pull changes' warnings — they mean SP metadata may be outdated
- Protect the clone from manual edits that cause pull conflicts
- Use HTTPS remotes with rotating-managed tokens rather than long-lived passwords
When it happens
Trigger: Any invocation of load() (via resolve, findByName, or findById) where the Git pull of the metadata repository fails: remote unreachable, bad credentials, corrupt/non-repository local directory, dirty working tree, or JGit pull returning false.
Common situations: Remote metadata Git server is down or firewalled; access token rotated/expired; someone committed directly into the clone causing pull conflicts; clone directory wiped and re-created without git init/clone.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- Unable to pull changes from the remote repository. Metadata…
- Metadata directory location cannot be located/created
- Unable to locate a valid SAML metadata resolver for to…
- No metadata resolvers could be configured for service with…
- LoggingUtils.warn(LOGGER, e)
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/5f84f5cf949ccf87.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-idp-metadata-git/src/main/java/org/apereo/cas/support/saml/metadata/resolver/GitSamlRegisteredServiceMetadataResolver.java:82
}
val metadataLocation = service.getMetadataLocation();
return metadataLocation != null
&& (metadataLocation.trim().startsWith(getSourceId())
|| (metadataLocation.trim().startsWith("http") && metadataLocation.trim().endsWith(".git")));
}
@Override
public String getSourceId() {
return "git://";
}
@Override
public List<SamlMetadataDocument> load() {
try {
if (gitRepository.pull()) {
LOGGER.debug("Successfully pulled metadata changes from the remote repository");
} else {
LOGGER.warn("Unable to pull changes from the remote repository. Metadata files may be stale.");
}
val repoDirectory = getMetadataDirectory();
val metadataFiles = FileUtils.listFiles(repoDirectory, new String[]{"xml"}, false);
return metadataFiles
.stream()
.map(GitSamlRegisteredServiceMetadataResolver::parseFileIntoSamlMetadataDocument)
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (final Exception e) {
LoggingUtils.error(LOGGER, e);
}
return List.of();
}
@Override
public SamlMetadataDocument store(final SamlMetadataDocument document) {
try {
document.assignIdIfNecessary();View on GitHub (pinned to e7288fc434)