diff --git a/configure.ac b/configure.ac
index 583b902361..84592f6041 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,16 +96,12 @@ m4_pattern_forbid([^GUIX_])
 
 dnl Search for 'guile' and 'guild'.  This macro defines
 dnl 'GUILE_EFFECTIVE_VERSION'.
-GUILE_PKG([3.0 2.2])
+GUILE_PKG([3.0])
 GUILE_PROGS
 if test "x$GUILD" = "x"; then
    AC_MSG_ERROR(['guild' binary not found; please check your Guile installation.])
 fi
 
-if test "x$GUILE_EFFECTIVE_VERSION" = "x2.2"; then
-  PKG_CHECK_MODULES([GUILE], [guile-2.2 >= 2.2.6])
-fi
-
 dnl Get CFLAGS and LDFLAGS for libguile.
 GUILE_FLAGS
 
diff --git a/doc/guix.texi b/doc/guix.texi
index e8b0485f78..05a4f9a6e2 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -833,8 +833,7 @@ GNU Guix is available for download from its website at
 GNU Guix depends on the following packages:
 
 @itemize
-@item @url{https://gnu.org/software/guile/, GNU Guile}, version 3.0.x or
-2.2.x;
+@item @url{https://gnu.org/software/guile/, GNU Guile}, version 3.0.x;
 @item @url{https://notabug.org/cwebber/guile-gcrypt, Guile-Gcrypt}, version
 0.1.0 or later;
 @item
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index 1cea8ed83d..6378d7c2d9 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -518,40 +518,6 @@ the Nix package manager.")
                (invoke "make" "install-binPROGRAMS")))
            (delete 'wrap-program)))))))
 
-
-(define-public guile2.2-guix
-  (package
-    (inherit guix)
-    (name "guile2.2-guix")
-    (native-inputs
-     `(("guile" ,guile-2.2)
-       ("gnutls" ,guile2.2-gnutls)
-       ("guile-gcrypt" ,guile2.2-gcrypt)
-       ("guile-json" ,guile2.2-json)
-       ("guile-lib" ,guile2.2-lib)
-       ("guile-sqlite3" ,guile2.2-sqlite3)
-       ("guile-ssh" ,guile2.2-ssh)
-       ("guile-git" ,guile2.2-git)
-       ("guile-zlib" ,guile2.2-zlib)
-       ("guile-lzlib" ,guile2.2-lzlib)
-       ,@(fold alist-delete (package-native-inputs guix)
-               '("guile" "gnutls" "guile-gcrypt" "guile-json"
-                 "guile-lib" "guile-sqlite3" "guile-ssh" "guile-git"
-                 "guile-zlib" "guile-lzlib"))))
-    (inputs
-     `(("guile" ,guile-2.2)
-       ,@(alist-delete "guile" (package-inputs guix))))
-    (propagated-inputs
-     `(("gnutls" ,gnutls)
-       ("guile-gcrypt" ,guile2.2-gcrypt)
-       ("guile-json" ,guile2.2-json)
-       ("guile-lib" ,guile2.2-lib)
-       ("guile-sqlite3" ,guile2.2-sqlite3)
-       ("guile-ssh" ,guile2.2-ssh)
-       ("guile-git" ,guile2.2-git)
-       ("guile-zlib" ,guile2.2-zlib)
-       ("guile-lzlib" ,guile2.2-lzlib)))))
-
 (define-public guile3.0-guix
   (deprecated-package "guile3.0-guix" guix))
 
diff --git a/guix/lint.scm b/guix/lint.scm
index a2d6418b85..023a179ea6 100644
--- a/guix/lint.scm
+++ b/guix/lint.scm
@@ -1003,14 +1003,9 @@ descriptions maintained upstream."
          (origin-uris origin))
         '())))
 
-(cond-expand
-  (guile-3
-   ;; Guile 3.0.0 does not export this predicate.
-   (define exception-with-kind-and-args?
-     (exception-predicate &exception-with-kind-and-args)))
-  (else                                           ;Guile 2
-   (define exception-with-kind-and-args?
-     (const #f))))
+;; Guile 3.0.0 does not export this predicate.
+(define exception-with-kind-and-args?
+  (exception-predicate &exception-with-kind-and-args))
 
 (define* (check-derivation package #:key store)
   "Emit a warning if we fail to compile PACKAGE to a derivation."
diff --git a/guix/scripts/deploy.scm b/guix/scripts/deploy.scm
index 0725fba54b..b2029943e2 100644
--- a/guix/scripts/deploy.scm
+++ b/guix/scripts/deploy.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 David Thompson <davet@gnu.org>
 ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
-;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2020, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -125,10 +125,7 @@ Perform the deployment specified by FILE.\n"))
            ;; and include a '&message'.  However, that message only contains
            ;; the format string.  Thus, special-case it here to avoid
            ;; displaying a bare format string.
-           ((cond-expand
-              (guile-3
-               ((exception-predicate &exception-with-kind-and-args) c))
-              (else #f))
+           (((exception-predicate &exception-with-kind-and-args) c)
             (raise c))
 
            ((message-condition? c)
diff --git a/guix/store.scm b/guix/store.scm
index 9d706ae590..cf5d5eeccc 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -648,18 +648,10 @@ connection.  Use with care."
             (close-connection store)
             (apply values results)))))
 
-    (cond-expand
-      (guile-3
-       (with-exception-handler (lambda (exception)
-                                 (close-connection store)
-                                 (raise-exception exception))
-         thunk))
-      (else                                       ;Guile 2.2
-       (catch #t
-         thunk
-         (lambda (key . args)
-           (close-connection store)
-           (apply throw key args)))))))
+    (with-exception-handler (lambda (exception)
+                              (close-connection store)
+                              (raise-exception exception))
+      thunk)))
 
 (define-syntax-rule (with-store store exp ...)
   "Bind STORE to an open connection to the store and evaluate EXPs;
diff --git a/guix/swh.scm b/guix/swh.scm
index 06d2957252..f6d5241e06 100644
--- a/guix/swh.scm
+++ b/guix/swh.scm
@@ -148,20 +148,12 @@
       url
       (string-append url "/")))
 
-(cond-expand
-  (guile-3
-   ;; XXX: Work around a bug in Guile 3.0.2 where #:verify-certificate? would
-   ;; be ignored (<https://bugs.gnu.org/40486>).
-   (define* (http-get* uri #:rest rest)
-     (apply http-request uri #:method 'GET rest))
-   (define* (http-post* uri #:rest rest)
-     (apply http-request uri #:method 'POST rest)))
-  (else                                           ;Guile 2.2
-   ;; Guile 2.2 did not have #:verify-certificate? so ignore it.
-   (define* (http-get* uri #:key verify-certificate? streaming?)
-     (http-request uri #:method 'GET #:streaming? streaming?))
-   (define* (http-post* uri #:key verify-certificate? streaming?)
-     (http-request uri #:method 'POST #:streaming? streaming?))))
+;; XXX: Work around a bug in Guile 3.0.2 where #:verify-certificate? would
+;; be ignored (<https://bugs.gnu.org/40486>).
+(define* (http-get* uri #:rest rest)
+  (apply http-request uri #:method 'GET rest))
+(define* (http-post* uri #:rest rest)
+  (apply http-request uri #:method 'POST rest))
 
 (define %date-regexp
   ;; Match strings like "2014-11-17T22:09:38+01:00" or
diff --git a/guix/ui.scm b/guix/ui.scm
index 05b3f5f84c..6b0155f563 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -196,17 +196,11 @@ information, or #f if it could not be found."
                            (stack-ref stack 1)    ;skip the 'throw' frame
                            last))))
 
-(cond-expand
-  (guile-3
-   (define-syntax-rule (without-compiler-optimizations exp)
-     ;; Compile with the baseline compiler (-O1), which is much less expensive
-     ;; than -O2.
-     (parameterize (((@ (system base compile) default-optimization-level) 1))
-       exp)))
-  (else
-   (define-syntax-rule (without-compiler-optimizations exp)
-     ;; No easy way to turn off optimizations on Guile 2.2.
-     exp)))
+(define-syntax-rule (without-compiler-optimizations exp)
+  ;; Compile with the baseline compiler (-O1), which is much less expensive
+  ;; than -O2.
+  (parameterize (((@ (system base compile) default-optimization-level) 1))
+    exp))
 
 (define* (load* file user-module
                 #:key (on-error 'nothing-special))
@@ -674,22 +668,17 @@ or variants of @code{~a} in the same profile.")
 or remove one of them from the profile.")
                               name1 name2)))))
 
-(cond-expand
-  (guile-3
-   ;; On Guile 3.0, in 'call-with-error-handling' we need to re-raise.  To
-   ;; preserve useful backtraces in case of unhandled errors, we want that to
-   ;; happen before the stack has been unwound, hence 'guard*'.
-   (define-syntax-rule (guard* (var clauses ...) exp ...)
-     "This variant of SRFI-34 'guard' does not unwind the stack before
+;; On Guile 3.0, in 'call-with-error-handling' we need to re-raise.  To
+;; preserve useful backtraces in case of unhandled errors, we want that to
+;; happen before the stack has been unwound, hence 'guard*'.
+(define-syntax-rule (guard* (var clauses ...) exp ...)
+  "This variant of SRFI-34 'guard' does not unwind the stack before
 evaluating the tests and bodies of CLAUSES."
-     (with-exception-handler
-         (lambda (var)
-           (cond clauses ... (else (raise var))))
-       (lambda () exp ...)
-       #:unwind? #f)))
-  (else
-   (define-syntax-rule (guard* (var clauses ...) exp ...)
-     (guard (var clauses ...) exp ...))))
+  (with-exception-handler
+      (lambda (var)
+        (cond clauses ... (else (raise var))))
+    (lambda () exp ...)
+    #:unwind? #f))
 
 (define (call-with-error-handling thunk)
   "Call THUNK within a user-friendly error handler."
@@ -822,10 +811,7 @@ directories:~{ ~a~}~%")
              ;; Furthermore, use of 'guard*' ensures that the stack has not
              ;; been unwound when we re-raise, since that would otherwise show
              ;; useless backtraces.
-             ((cond-expand
-                (guile-3
-                 ((exception-predicate &exception-with-kind-and-args) c))
-                (else #f))
+             (((exception-predicate &exception-with-kind-and-args) c)
               (raise c))
 
              ((message-condition? c)
