diff --git a/lib/modules/datasource/packagist/index.spec.ts b/lib/modules/datasource/packagist/index.spec.ts
index 845c19082fdd889a142dc7004d8e052ad00f178f..c82a69ccac52fe072d9ac081028d9fbe70edd10c 100644
--- a/lib/modules/datasource/packagist/index.spec.ts
+++ b/lib/modules/datasource/packagist/index.spec.ts
@@ -176,6 +176,67 @@ describe('modules/datasource/packagist/index', () => {
       expect(res).not.toBeNull();
     });
 
+    it('supports older sha1 hashes', async () => {
+      hostRules.find = jest.fn(() => ({
+        username: 'some-username',
+        password: 'some-password',
+      }));
+      const packagesJson = {
+        packages: [],
+        includes: {
+          'include/all$afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b.json': {
+            sha1: 'afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b',
+          },
+        },
+      };
+      httpMock
+        .scope('https://composer.renovatebot.com')
+        .get('/packages.json')
+        .reply(200, packagesJson)
+        .get('/include/all$afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b.json')
+        .reply(200, includesJson);
+      const res = await getPkgReleases({
+        ...config,
+        datasource,
+        versioning,
+        depName: 'guzzlehttp/guzzle',
+      });
+      expect(res).toMatchObject({
+        homepage: 'http://guzzlephp.org/',
+        registryUrl: 'https://composer.renovatebot.com',
+        releases: [
+          { version: '3.0.0' },
+          { version: '3.0.1' },
+          { version: '3.0.2' },
+          { version: '3.0.3' },
+          { version: '3.0.4' },
+          { version: '3.0.5' },
+          { version: '3.0.6' },
+          { version: '3.0.7' },
+          { version: '3.1.0' },
+          { version: '3.1.1' },
+          { version: '3.1.2' },
+          { version: '3.2.0' },
+          { version: '3.3.0' },
+          { version: '3.3.1' },
+          { version: '3.4.0' },
+          { version: '3.4.1' },
+          { version: '3.4.2' },
+          { version: '3.4.3' },
+          { version: '3.5.0' },
+          { version: '3.6.0' },
+          { version: '3.7.0' },
+          { version: '3.7.1' },
+          { version: '3.7.2' },
+          { version: '3.7.3' },
+          { version: '3.7.4' },
+          { version: '3.8.0' },
+          { version: '3.8.1' },
+        ],
+        sourceUrl: 'https://github.com/guzzle/guzzle',
+      });
+    });
+
     it('supports lazy repositories', async () => {
       const packagesJson = {
         packages: [],
diff --git a/lib/modules/datasource/packagist/index.ts b/lib/modules/datasource/packagist/index.ts
index 8d902f99f39174c79046ff8981a8ca5a1eb1e7d4..9928405698b24875bb0300ee9285a201fc296106 100644
--- a/lib/modules/datasource/packagist/index.ts
+++ b/lib/modules/datasource/packagist/index.ts
@@ -68,8 +68,8 @@ export class PackagistDatasource extends Datasource {
     regUrl: string,
     regFile: RegistryFile
   ): string {
-    const { key, sha256 } = regFile;
-    const fileName = key.replace('%hash%', sha256);
+    const { key, hash } = regFile;
+    const fileName = hash ? key.replace('%hash%', hash) : key;
     const url = `${regUrl}/${fileName}`;
     return url;
   }
diff --git a/lib/modules/datasource/packagist/schema.ts b/lib/modules/datasource/packagist/schema.ts
index d71a9b27da9cec396d63acd3a8d04886c383f932..0205605fb9aca2d2a91e33e8c2616d52d27f9b66 100644
--- a/lib/modules/datasource/packagist/schema.ts
+++ b/lib/modules/datasource/packagist/schema.ts
@@ -155,10 +155,20 @@ export function parsePackagesResponses(
   return extractReleaseResult(...releaseArrays);
 }
 
-export const RegistryFile = z.object({
-  key: z.string(),
-  sha256: z.string(),
-});
+export const HashSpec = z.union([
+  z
+    .object({ sha256: z.string().nullable() })
+    .transform(({ sha256 }) => ({ hash: sha256 })),
+  z
+    .object({ sha1: z.string().nullable() })
+    .transform(({ sha1 }) => ({ hash: sha1 })),
+]);
+export type HashSpec = z.infer<typeof HashSpec>;
+
+export const RegistryFile = z.intersection(
+  HashSpec,
+  z.object({ key: z.string() })
+);
 export type RegistryFile = z.infer<typeof RegistryFile>;
 
 export const PackagesResponse = z.object({
@@ -168,13 +178,9 @@ export type PackagesResponse = z.infer<typeof PackagesResponse>;
 
 export const PackagistFile = PackagesResponse.merge(
   z.object({
-    providers: looseRecord(
-      z.object({
-        sha256: looseValue(z.string()),
-      })
-    ).transform((x) =>
+    providers: looseRecord(HashSpec).transform((x) =>
       Object.fromEntries(
-        Object.entries(x).map(([key, { sha256 }]) => [key, sha256])
+        Object.entries(x).map(([key, { hash }]) => [key, hash])
       )
     ),
   })
@@ -186,22 +192,11 @@ export const RegistryMeta = z
     (x) => (is.plainObject(x) ? x : {}),
     PackagistFile.merge(
       z.object({
-        ['includes']: looseRecord(
-          z.object({
-            sha256: z.string(),
-          })
-        ).transform((x) =>
-          Object.entries(x).map(([name, { sha256 }]) => ({
-            key: name.replace(sha256, '%hash%'),
-            sha256,
-          }))
+        ['includes']: looseRecord(HashSpec).transform((x) =>
+          Object.entries(x).map(([name, { hash }]) => ({ key: name, hash }))
         ),
-        ['provider-includes']: looseRecord(
-          z.object({
-            sha256: z.string(),
-          })
-        ).transform((x) =>
-          Object.entries(x).map(([key, { sha256 }]) => ({ key, sha256 }))
+        ['provider-includes']: looseRecord(HashSpec).transform((x) =>
+          Object.entries(x).map(([key, { hash }]) => ({ key, hash }))
         ),
         ['providers-lazy-url']: looseValue(z.string()),
         ['providers-url']: looseValue(z.string()),