diff --git a/guix/utils.scm b/guix/utils.scm
index c321ad9943f9e7c4618b46a320b72d4f4da7e640..f8b05e7e805e9593e08b9b98daa59b12fc2c7705 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -210,7 +210,13 @@ (define (lzip-port proc port . args)
   "Return the lzip port produced by calling PROC (a symbol) on PORT and ARGS.
 Raise an error if lzlib support is missing."
   (let ((make-port (module-ref (resolve-interface '(lzlib)) proc)))
-    (values (make-port port) '())))
+    (make-port port)))
+
+(define (zstd-port proc port . args)
+  "Return the zstd port produced by calling PROC (a symbol) on PORT and ARGS.
+Raise an error if zstd support is missing."
+  (let ((make-port (module-ref (resolve-interface '(zstd)) proc)))
+    (make-port port)))
 
 (define (decompressed-port compression input)
   "Return an input port where INPUT is decompressed according to COMPRESSION,
@@ -222,6 +228,8 @@ (define (decompressed-port compression input)
     ('gzip         (filtered-port `(,%gzip "-dc") input))
     ('lzip         (values (lzip-port 'make-lzip-input-port input)
                            '()))
+    ('zstd         (values (zstd-port 'make-zstd-input-port input)
+                           '()))
     (_             (error "unsupported compression scheme" compression))))
 
 (define (call-with-decompressed-port compression port proc)
@@ -281,6 +289,8 @@ (define* (compressed-output-port compression output
     ('gzip         (filtered-output-port `(,%gzip "-c" ,@options) output))
     ('lzip         (values (lzip-port 'make-lzip-output-port output)
                            '()))
+    ('zstd         (values (zstd-port 'make-zstd-output-port output)
+                           '()))
     (_             (error "unsupported compression scheme" compression))))
 
 (define* (call-with-compressed-output-port compression port proc
diff --git a/tests/utils.scm b/tests/utils.scm
index c278b2a2778091509b54b63affe548e114e923b0..9bce446d98f416dfff013a8b35bce3b8bf1c7b11 100644
--- a/tests/utils.scm
+++ b/tests/utils.scm
@@ -228,8 +228,10 @@ (define (test-compression/decompression method run?)
                       get-bytevector-all)))))
 
 (for-each test-compression/decompression
-          '(gzip xz lzip)
-          (list (const #t) (const #t) (const #t)))
+          `(gzip xz lzip zstd)
+          (list (const #t) (const #t) (const #t)
+                (lambda ()
+                  (resolve-module '(zstd) #t #f #:ensure #f))))
 
 ;; This is actually in (guix store).
 (test-equal "store-path-package-name"