diff --git a/RECIPE-API-CHANGELOG.md b/RECIPE-API-CHANGELOG.md
index 3798a9d1..4711fb72 100644
--- a/RECIPE-API-CHANGELOG.md
+++ b/RECIPE-API-CHANGELOG.md
@@ -1225,3 +1225,17 @@ the rootfs. This has been replaced by the `exclude-docs` rootfs feature. The
 
 When enabled, the package changelogs are now removed as well (copyright is still
 kept for legal reasons).
+
+### Debian source package is generated from the -native variant
+
+Previously, the base recipe (`${BPN}`) built the source package while all other
+variants merely fetched the resulting artifact. When building for multiple
+architectures, every one of them produced its own source package, even though
+only a single one is ever deployed to `DEPLOY_DIR_SRC`.
+
+Since the source package is architecture independent, it is now always built by
+the `-native` variant. Only the `do_dpkg_source` task of that variant has to be
+runnable, the variant itself does not need to build to completion. In addition,
+the name and the content of the source package must be derived from `${BPN}`
+alone, never from `${PN}`. If a source package depends on the architecture,
+set `SRCPKG_PROVIDER = "${BPN}"` after `inherit dpkg` (or alike).
diff --git a/meta/classes-recipe/container-loader.bbclass b/meta/classes-recipe/container-loader.bbclass
index 8439db53..31c6e245 100644
--- a/meta/classes-recipe/container-loader.bbclass
+++ b/meta/classes-recipe/container-loader.bbclass
@@ -17,6 +17,7 @@ DEBIAN_PROVIDES := "${BPN}"
 PN .= "-${DISTRO_ARCH}"
 DPKG_ARCH ?= "${DISTRO_ARCH}"
 DEBIAN_MULTI_ARCH ?= "allowed"
+SRCPKG_PROVIDER = "${BPN}"
 
 CONTAINER_DELETE_AFTER_LOAD ?= "0"
 
diff --git a/meta/classes-recipe/dpkg-source.bbclass b/meta/classes-recipe/dpkg-source.bbclass
index 6f9091a8..16d423d3 100644
--- a/meta/classes-recipe/dpkg-source.bbclass
+++ b/meta/classes-recipe/dpkg-source.bbclass
@@ -82,75 +82,18 @@ do_deploy_source() {
 }
 addtask deploy_source after do_dpkg_source
 
-do_dpkg_build[depends] += "${BPN}:do_deploy_source"
+# The source package is architecture independent, so it is owned by the -native
+# variant when cross building. Without one, the base recipe also provides
+# ${BPN}-native (see multiarch.bbclass), so this resolves in both cases.
+SRCPKG_PROVIDER = "${@'${BPN}-native' if d.getVar('HOST_ARCH') != d.getVar('DISTRO_ARCH') else '${BPN}'}"
+
+do_dpkg_build[depends] += "${SRCPKG_PROVIDER}:do_deploy_source"
 # ensure that the source package is deployed into isar-apt
-do_deploy_deb[rdepends] += "${BPN}:do_deploy_source"
+do_deploy_deb[rdepends] += "${SRCPKG_PROVIDER}:do_deploy_source"
 
 SCHROOT_MOUNTS = "${WORKDIR}:/work ${REPO_ISAR_DIR}/${DISTRO}:/isar-apt"
 
-fetch_common_source_schroot() {
-    schroot_create_configs
-    insert_mounts
-
-    session_id=$(schroot -q -b -c ${SBUILD_CHROOT})
-    echo "Started session: ${session_id}"
-
-    schroot_cleanup() {
-        schroot -q -f -e -c ${session_id} > /dev/null 2>&1
-        remove_mounts > /dev/null 2>&1
-        schroot_delete_configs
-    }
-    trap 'exit 1' INT HUP QUIT TERM ALRM USR1
-    trap 'schroot_cleanup' EXIT
-
-    E="${@ isar_export_proxies(d)}"
-
-    schroot -r -c ${session_id} -d / -u root -- \
-        apt-get update -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" -o Dir::Etc::SourceParts="-" -o APT::Get::List-Cleanup="0"
-    schroot -r -c ${session_id} -d / -- \
-        sh -c '
-            cd /work
-            apt-get -y --download-only --only-source -o Debug::NoLocking=1 -o Acquire::Source-Symlinks="false" source ${DEBIAN_SOURCE}'
-
-    schroot -e -c ${session_id}
-    remove_mounts
-    schroot_delete_configs
-}
-
-UNSHARE_DPKG_SOURCE_CHROOT = "${WORKDIR}/dpkg-source-chroot"
-fetch_common_source_unshare() {
-    run_privileged_heredoc <<'EOF'
-        set -e
-        mkdir -p ${UNSHARE_DPKG_SOURCE_CHROOT}
-        tar -xf "${SBUILD_CHROOT}" -C ${UNSHARE_DPKG_SOURCE_CHROOT}
-
-        ${@insert_isar_mounts(d, d.getVar('UNSHARE_DPKG_SOURCE_CHROOT'), d.getVar('SCHROOT_MOUNTS'))}
-        chroot ${UNSHARE_DPKG_SOURCE_CHROOT} /bin/bash -s <<'EOAPT'
-            set -e
-            apt-get update \
-                -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \
-                -o Dir::Etc::SourceParts="-" \
-                -o APT::Get::List-Cleanup="0"
-
-            cd /work
-            apt-get -y --download-only --only-source \
-                -o Debug::NoLocking=1 -o Acquire::Source-Symlinks="false"  \
-                source ${DEBIAN_SOURCE}
-EOAPT
-EOF
-
-    # run cleanup in separate session to ensure nothing is mounted
-    run_privileged rm -rf ${UNSHARE_DPKG_SOURCE_CHROOT}
-}
-
-do_fetch_common_source[depends] += "${SCHROOT_DEP} ${BPN}:do_deploy_source"
-do_fetch_common_source[lockfiles] = "${REPO_ISAR_DIR}/isar.lock"
-do_fetch_common_source[network] = "${TASK_USE_SUDO}"
-do_fetch_common_source[depends] += "base-apt:do_cache isar-apt:do_cache_config"
-do_fetch_common_source() {
-    fetch_common_source_${ISAR_CHROOT_MODE}
-}
-addtask fetch_common_source
-
-do_dpkg_build[depends] += "${@'${PN}:do_dpkg_source' if '${PN}' == '${BPN}' else '${PN}:do_fetch_common_source'}"
-do_clean[depends] += "${@'' if '${PN}' == '${BPN}' else '${BPN}:do_clean'}"
+# All variants share BPN and thus DEPLOY_DIR_SRC, so only the provider builds a
+# source package, everybody else consumes the one deployed there.
+do_dpkg_build[depends] += "${SRCPKG_PROVIDER}:do_dpkg_source"
+do_clean[depends] += "${@'' if '${PN}' == '${SRCPKG_PROVIDER}' else '${SRCPKG_PROVIDER}:do_clean'}"
diff --git a/meta/classes-recipe/linux-kernel.bbclass b/meta/classes-recipe/linux-kernel.bbclass
index ac587b17..60bf2a49 100644
--- a/meta/classes-recipe/linux-kernel.bbclass
+++ b/meta/classes-recipe/linux-kernel.bbclass
@@ -102,6 +102,9 @@ inherit dpkg
 inherit kbuildtarget
 inherit libctarget
 
+# The kernel source package is architecture specific
+SRCPKG_PROVIDER = "${BPN}"
+
 # Add custom cflags to the kernel build
 KCFLAGS ?= "-fdebug-prefix-map=${CURDIR}=."
 KAFLAGS ?= "-fdebug-prefix-map=${CURDIR}=."
diff --git a/meta/classes-recipe/linux-module.bbclass b/meta/classes-recipe/linux-module.bbclass
index 05a36129..76bf03f7 100644
--- a/meta/classes-recipe/linux-module.bbclass
+++ b/meta/classes-recipe/linux-module.bbclass
@@ -51,6 +51,9 @@ python() {
 inherit dpkg
 inherit per-kernel
 
+# The kernel module source package is architecture specific
+SRCPKG_PROVIDER = "${BPN}"
+
 TEMPLATE_FILES = "debian/control.tmpl \
                   debian/rules.tmpl"
 TEMPLATE_VARS += " \
