diff --git a/bin/xbps-install/state_cb.c b/bin/xbps-install/state_cb.c
index e40ef654..2960bcf3 100644
--- a/bin/xbps-install/state_cb.c
+++ b/bin/xbps-install/state_cb.c
@@ -158,6 +158,18 @@ state_cb(const struct xbps_state_cb_data *xscd, void *cbdata UNUSED)
 	case XBPS_STATE_UNPACK_FILE_PRESERVED:
 		printf("%s\n", xscd->desc);
 		break;
+	case XBPS_STATE_OUTOFDATE:
+		if (!xbps_pkg_name(pkgname, sizeof(pkgname), xscd->arg)) {
+			abort();
+		}
+		newver = xscd->arg;
+		pkgd = xbps_pkgdb_get_pkg(xscd->xhp, pkgname);
+		xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &instver);
+		fprintf(stderr, "WARNING: The '%s' package is out of date, '%s' is available.\n", instver, newver);
+		if (xscd->desc)
+			fprintf(stderr, "%s\n", xscd->desc);
+		fprintf(stderr, "NOTE: This can be resolved by running `xbps-install -u`\n");
+		break;
 	/* errors */
 	case XBPS_STATE_TRANS_FAIL:
 	case XBPS_STATE_UNPACK_FAIL:
diff --git a/bin/xbps-install/transaction.c b/bin/xbps-install/transaction.c
index d2fac3b0..58fdace8 100644
--- a/bin/xbps-install/transaction.c
+++ b/bin/xbps-install/transaction.c
@@ -316,13 +316,6 @@ dist_upgrade(struct xbps_handle *xhp, unsigned int cols, bool yes, bool drun)
 	if (rv == ENOENT) {
 		xbps_error_printf("No packages currently registered.\n");
 		return 0;
-	} else if (rv == EBUSY) {
-		if (drun) {
-			rv = 0;
-		} else {
-			xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
-			return rv;
-		}
 	} else if (rv == EEXIST) {
 		return 0;
 	} else if (rv == ENOTSUP) {
@@ -350,8 +343,6 @@ install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
 		xbps_error_printf("No repositories currently registered!\n");
 	else if (rv == ENXIO)
 		xbps_error_printf("Package `%s' contains invalid dependencies, exiting.\n", pkg);
-	else if (rv == EBUSY)
-		xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
 	else if (rv != 0) {
 		xbps_error_printf("Unexpected error: %s\n", strerror(rv));
 		rv = -1;
@@ -375,8 +366,6 @@ update_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
 		xbps_error_printf("No repositories currently registered!\n");
 	else if (rv == ENXIO)
 		xbps_error_printf("Package `%s' contains invalid dependencies, exiting.\n", pkg);
-	else if (rv == EBUSY)
-		xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
 	else if (rv != 0) {
 		xbps_error_printf("Unexpected error: %s\n", strerror(rv));
 		return -1;
diff --git a/include/xbps.h.in b/include/xbps.h.in
index 226c42a7..deb8eff6 100644
--- a/include/xbps.h.in
+++ b/include/xbps.h.in
@@ -374,7 +374,8 @@ typedef enum xbps_state {
 	XBPS_STATE_ALTGROUP_REMOVED,
 	XBPS_STATE_ALTGROUP_SWITCHED,
 	XBPS_STATE_ALTGROUP_LINK_ADDED,
-	XBPS_STATE_ALTGROUP_LINK_REMOVED
+	XBPS_STATE_ALTGROUP_LINK_REMOVED,
+	XBPS_STATE_OUTOFDATE
 } xbps_state_t;
 
 /**
diff --git a/lib/cb_util.c b/lib/cb_util.c
index 35fbaa77..b3ca9e00 100644
--- a/lib/cb_util.c
+++ b/lib/cb_util.c
@@ -82,6 +82,7 @@ xbps_set_cb_state(struct xbps_handle *xhp,
 	xscd.state = state;
 	xscd.err = err;
 	xscd.arg = arg;
+	xscd.desc = NULL;
 	if (fmt != NULL) {
 		va_start(va, fmt);
 		retval = vasprintf(&buf, fmt, va);
diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c
index d4fef601..1ee087c9 100644
--- a/lib/transaction_ops.c
+++ b/lib/transaction_ops.c
@@ -226,19 +226,18 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
  * Returns 1 if there's an update, 0 if none or -1 on error.
  */
 static int
-xbps_autoupdate(struct xbps_handle *xhp)
+trans_check_uptodate(struct xbps_handle *xhp, const char *checkpkg, const char **new_pkgver)
 {
-	xbps_array_t rdeps;
-	xbps_dictionary_t pkgd;
-	const char *pkgver = NULL, *pkgname = NULL;
-	int rv;
+	xbps_array_t pkgs;
+	xbps_dictionary_t pkgd = NULL, pkg_repod = NULL;
+	const char *pkgver = NULL, *pkgname = NULL, *repopkgver = NULL, *repoloc = NULL;
 
 	/*
 	 * Check if there's a new update for XBPS before starting
 	 * another transaction.
 	 */
-	if (((pkgd = xbps_pkgdb_get_pkg(xhp, "xbps")) == NULL) &&
-	    ((pkgd = xbps_pkgdb_get_virtualpkg(xhp, "xbps")) == NULL))
+	if (((pkgd = xbps_pkgdb_get_pkg(xhp, checkpkg)) == NULL) &&
+	    ((pkgd = xbps_pkgdb_get_virtualpkg(xhp, checkpkg)) == NULL))
 		return 0;
 
 	if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver)) {
@@ -248,52 +247,59 @@ xbps_autoupdate(struct xbps_handle *xhp)
 		return EINVAL;
 	}
 
-	rv = trans_find_pkg(xhp, pkgname, false);
-
-	xbps_dbg_printf("%s: trans_find_pkg xbps: %d\n", __func__, rv);
-
-	if (rv == 0) {
-		if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
+	if (xbps_dictionary_get(pkgd, "repolock")) {
+		struct xbps_repo *repo;
+		/* find update from repo */
+		xbps_dictionary_get_cstring_nocopy(pkgd, "repository", &repoloc);
+		assert(repoloc);
+		if ((repo = xbps_regget_repo(xhp, repoloc)) == NULL) {
+			/* not found */
 			return 0;
 		}
-		/* a new xbps version is available, check its revdeps */
-		rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps");
-		for (unsigned int i = 0; i < xbps_array_count(rdeps); i++)  {
-			const char *curpkgver = NULL;
-			char curpkgn[XBPS_NAME_SIZE] = {0};
+		pkg_repod = xbps_repo_get_pkg(repo, pkgname);
+	} else {
+		/* find update from rpool */
+		pkg_repod = xbps_rpool_get_pkg(xhp, pkgname);
+	}
+	if (pkg_repod == NULL) {
+		/* not found */
+		return 0;
+	}
 
-			xbps_array_get_cstring_nocopy(rdeps, i, &curpkgver);
-			xbps_dbg_printf("%s: processing revdep %s\n", __func__, curpkgver);
+	xbps_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &repopkgver);
+	
+	/*
+	 * Compare installed version vs best pkg available in repos
+	 * for pkg updates.
+	 */
+	xbps_dictionary_get_cstring_nocopy(pkgd,
+	    "pkgver", &pkgver);
+	if (xbps_cmpver(repopkgver, pkgver) <= 0 &&
+	    !xbps_pkg_reverts(pkg_repod, pkgver)) {
+		xbps_dictionary_get_cstring_nocopy(pkg_repod,
+		    "repository", &repoloc);
+		xbps_dbg_printf("%s: [rpool] Skipping `%s' "
+		    "(installed: %s) from repository `%s'\n",
+		    __func__, repopkgver, pkgver, repoloc);
+		return 0;
+	}
 
-			if (!xbps_pkg_name(curpkgn, sizeof(curpkgn), curpkgver)) {
-				abort();
-			}
-			rv = trans_find_pkg(xhp, curpkgn, false);
-			xbps_dbg_printf("%s: trans_find_pkg revdep %s: %d\n", __func__, curpkgver, rv);
-			if (rv && rv != ENOENT && rv != EEXIST && rv != ENODEV)
-				return -1;
-		}
-		/*
-		 * Set XBPS_FLAG_FORCE_REMOVE_REVDEPS to ignore broken
-		 * reverse dependencies in xbps_transaction_prepare().
-		 *
-		 * This won't skip revdeps of the xbps pkg, rather other
-		 * packages in rootdir that could be broken indirectly.
-		 *
-		 * A sysup transaction after updating xbps should fix them
-		 * again.
-		 */
-		xhp->flags |= XBPS_FLAG_FORCE_REMOVE_REVDEPS;
-		return 1;
-	} else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
-		/* no update */
+	pkgs = xbps_dictionary_get(xhp->transd, "packages");
+	/*
+	 * Find out if package being checked already has a queued
+	 * transaction, in that case ignore it.
+	 */
+	if (xbps_find_pkg_in_array(pkgs, repopkgver, 0)) {
+		xbps_dbg_printf("%s: [update] `%s' already queued in "
+		    "transaction.\n", __func__, repopkgver);
 		return 0;
-	} else {
-		/* error */
-		return -1;
 	}
 
-	return 0;
+	if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
+		return 0;
+	}
+	if (new_pkgver) *new_pkgver = repopkgver;
+	return 1;
 }
 
 int
@@ -305,17 +311,8 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
 	bool newpkg_found = false;
 	int rv = 0;
 
-	rv = xbps_autoupdate(xhp);
-	switch (rv) {
-	case 1:
-		/* xbps needs to be updated, don't allow any other update */
-		return EBUSY;
-	case -1:
-		/* error */
+	if (xbps_pkgdb_init(xhp) != 0)
 		return EINVAL;
-	default:
-		break;
-	}
 
 	iter = xbps_dictionary_iterator(xhp->pkgdb);
 	assert(iter);
@@ -346,6 +343,13 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
 	}
 	xbps_object_iterator_release(iter);
 
+	/* Notify consumer if xbps is out of date */
+	{
+		const char *pkgver = NULL;
+		if (trans_check_uptodate(xhp, "xbps", &pkgver) == 1)
+			xbps_set_cb_state(xhp, XBPS_STATE_OUTOFDATE, 0, pkgver, NULL);
+	}
+
 	return newpkg_found ? rv : EEXIST;
 }
 
@@ -355,22 +359,6 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg, bool force
 	xbps_array_t rdeps;
 	int rv;
 
-	rv = xbps_autoupdate(xhp);
-	xbps_dbg_printf("%s: xbps_autoupdate %d\n", __func__, rv);
-	switch (rv) {
-	case 1:
-		/* xbps needs to be updated, only allow xbps to be updated */
-		if (strcmp(pkg, "xbps"))
-			return EBUSY;
-		return 0;
-	case -1:
-		/* error */
-		return EINVAL;
-	default:
-		/* no update */
-		break;
-	}
-
 	/* update its reverse dependencies */
 	rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg);
 	if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
@@ -397,6 +385,14 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg, bool force
 	/* add pkg repod */
 	rv = trans_find_pkg(xhp, pkg, force);
 	xbps_dbg_printf("%s: trans_find_pkg %s: %d\n", __func__, pkg, rv);
+
+	/* Notify consumer if xbps is out of date */
+	{
+		const char *pkgver = NULL;
+		if (trans_check_uptodate(xhp, "xbps", &pkgver) == 1)
+			xbps_set_cb_state(xhp, XBPS_STATE_OUTOFDATE, 0, pkgver, NULL);
+	}
+
 	return rv;
 }
 
@@ -406,21 +402,6 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool forc
 	xbps_array_t rdeps;
 	int rv;
 
-	rv = xbps_autoupdate(xhp);
-	switch (rv) {
-	case 1:
-		/* xbps needs to be updated, only allow xbps to be updated */
-		if (strcmp(pkg, "xbps"))
-			return EBUSY;
-		return 0;
-	case -1:
-		/* error */
-		return EINVAL;
-	default:
-		/* no update */
-		break;
-	}
-
 	/* update its reverse dependencies */
 	rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg);
 	if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
@@ -446,6 +427,14 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool forc
 	}
 	rv = trans_find_pkg(xhp, pkg, force);
 	xbps_dbg_printf("%s: trans_find_pkg %s: %d\n", __func__, pkg, rv);
+
+	/* Notify consumer if xbps is out of date */
+	{
+		const char *pkgver = NULL;
+		if (trans_check_uptodate(xhp, "xbps", &pkgver) == 1)
+			xbps_set_cb_state(xhp, XBPS_STATE_OUTOFDATE, 0, pkgver, NULL);
+	}
+
 	return rv;
 }
 
diff --git a/tests/xbps/libxbps/shell/install_test.sh b/tests/xbps/libxbps/shell/install_test.sh
index c0fe9a1a..98b744fb 100644
--- a/tests/xbps/libxbps/shell/install_test.sh
+++ b/tests/xbps/libxbps/shell/install_test.sh
@@ -484,10 +484,7 @@ update_xbps_body() {
 	cd ..
 	xbps-rindex -d -a repo/*.xbps
 	atf_check_equal $? 0
-	out=$(xbps-install -r root --repository=repo -yun)
-	set -- $out
-	exp="$1 $2 $3 $4"
-	atf_check_equal "$exp" "xbps-1.1_1 update noarch $(readlink -f repo)"
+	atf_check -s exit:0 -o ignore -e match:"^WARNING: The 'xbps-1\.0_1' package is out of date, 'xbps-1\.1_1' is available\.$" -- xbps-install -r root --repository=repo -yn B
 
 	xbps-install -r root --repository=repo -yu xbps
 	atf_check_equal $? 0
@@ -537,10 +534,7 @@ update_xbps_virtual_body() {
 	cd ..
 	xbps-rindex -d -a repo/*.xbps
 	atf_check_equal $? 0
-	out=$(xbps-install -r root --repository=repo -yun)
-	set -- $out
-	exp="$1 $2 $3 $4"
-	atf_check_equal "$exp" "xbps-git-1.1_1 update noarch $(readlink -f repo)"
+	atf_check -s exit:0 -o ignore -e match:"^WARNING: The 'xbps-git-1\.0_1' package is out of date, 'xbps-git-1\.1_1' is available\.$" -- xbps-install -r root --repository=repo -yn B
 
 	xbps-install -r root --repository=repo -yu xbps
 	atf_check_equal $? 0
diff --git a/tests/xbps/libxbps/shell/update_itself_test.sh b/tests/xbps/libxbps/shell/update_itself_test.sh
index 1045ac3a..8d3c8ae7 100644
--- a/tests/xbps/libxbps/shell/update_itself_test.sh
+++ b/tests/xbps/libxbps/shell/update_itself_test.sh
@@ -7,17 +7,20 @@ update_xbps_head() {
 }
 
 update_xbps_body() {
-	mkdir -p repo xbps
+	mkdir -p repo xbps bar
 	touch xbps/foo
+	touch bar/bar
 
 	cd repo
 	xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" ../xbps
 	atf_check_equal $? 0
+	xbps-create -A noarch -n bar-1.0_1 -s "bar pkg" ../bar
+	atf_check_equal $? 0
 	xbps-rindex -d -a $PWD/*.xbps
 	atf_check_equal $? 0
 	cd ..
 
-	xbps-install -r root --repository=$PWD/repo -yd xbps
+	xbps-install -r root --repository=$PWD/repo -yd xbps bar
 	atf_check_equal $? 0
 
 	out=$(xbps-query -r root -p pkgver xbps)
@@ -26,13 +29,17 @@ update_xbps_body() {
 	cd repo
 	xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps
 	atf_check_equal $? 0
-	xbps-rindex -d -a $PWD/xbps-1.1_1.noarch.xbps
+	xbps-create -A noarch -n bar-1.1_1 -s "bar pkg" ../bar
+	atf_check_equal $? 0
+	xbps-rindex -d -a $PWD/*.xbps
 	atf_check_equal $? 0
 	cd ..
 
-	# EBUSY
-	xbps-install -r root --repository=$PWD/repo -yud
-	atf_check_equal $? 16
+	# Ensure warning is printed
+	atf_check -s exit:0 -o ignore -e match:"^WARNING: The 'xbps-1\.0_1' package is out of date, 'xbps-1\.1_1' is available\.$" -- xbps-install -r root --repository=$PWD/repo -yd bar
+
+	out=$(xbps-query -r root -p pkgver bar)
+	atf_check_equal $out bar-1.1_1
 
 	out=$(xbps-query -r root -p pkgver xbps)
 	atf_check_equal $out xbps-1.0_1
@@ -51,8 +58,8 @@ update_xbps_with_revdeps_head() {
 }
 
 update_xbps_with_revdeps_body() {
-	mkdir -p repo xbps xbps-dbg baz
-	touch xbps/foo xbps-dbg/bar baz/blah
+	mkdir -p repo xbps xbps-dbg bar baz
+	touch xbps/foo xbps-dbg/bar bar/sailor baz/blah
 
 	cd repo
 	xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" ../xbps
@@ -67,6 +74,8 @@ update_xbps_with_revdeps_body() {
 	cd repo
 	xbps-create -A noarch -n baz-1.0_1 -s "baz pkg" ../baz
 	atf_check_equal $? 0
+	xbps-create -A noarch -n bar-1.0_1 -s "bar pkg" ../bar
+	atf_check_equal $? 0
 	xbps-create -A noarch -n xbps-dbg-1.0_1 -s "xbps-dbg pkg" --dependencies "xbps-1.0_1" ../xbps-dbg
 	atf_check_equal $? 0
 	xbps-rindex -d -a $PWD/*.xbps
@@ -87,12 +96,11 @@ update_xbps_with_revdeps_body() {
 	atf_check_equal $? 0
 	cd ..
 
-	# first time, xbps must be updated (returns EBUSY)
-	xbps-install -r root --repository=$PWD/repo -yud
-	atf_check_equal $? 16
+	# first time, warning must be printed
+	atf_check -s exit:0 -o ignore -e match:"^WARNING: The 'xbps-1\.0_1' package is out of date, 'xbps-1\.1_1' is available\.$" -- xbps-install -r root --repository=$PWD/repo -yd bar
 
-	xbps-install -r root --repository=$PWD/repo -yu xbps
-	atf_check_equal $? 0
+	# don't print warning while updating xbps
+	atf_check -s exit:0 -o ignore -e not-match:"^WARNING: The 'xbps-1\.0_1' package is out of date, 'xbps-1\.1_1' is available\.$" -- xbps-install -r root --repository=$PWD/repo -yu xbps
 
 	out=$(xbps-query -r root -p pkgver xbps)
 	atf_check_equal $out xbps-1.1_1
@@ -152,11 +160,8 @@ update_xbps_with_uptodate_revdeps_body() {
 	atf_check_equal $? 0
 	cd ..
 
-	xbps-install -r root --repository=$PWD/repo -yud
-	atf_check_equal $? 16
-
-	xbps-install -r root --repository=$PWD/repo -yu xbps
-	atf_check_equal $? 0
+	# don't print warning while updating xbps
+	atf_check -s exit:0 -o ignore -e not-match:"^WARNING: The 'xbps-1\.0_1' package is out of date, 'xbps-1\.1_1' is available\.$" -- xbps-install -r root --repository=$PWD/repo -yu xbps
 
 	out=$(xbps-query -r root -p pkgver xbps)
 	atf_check_equal $out xbps-1.1_1
@@ -174,6 +179,8 @@ update_xbps_with_indirect_revdeps_head() {
 update_xbps_with_indirect_revdeps_body() {
 	mkdir -p repo pkg
 
+	atf_expect_fail "Integrity checks are no longer bypassed for xbps self-update: https://github.com/void-linux/xbps/pull/597"
+
 	cd repo
 	xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" --dependencies "libcrypto-1.0_1 cacerts>=0" ../pkg
 	atf_check_equal $? 0