diff --git a/config/user-nptl_guard_within_stack.m4 b/config/user-nptl_guard_within_stack.m4
new file mode 100644
index 0000000000..d094da7332
--- /dev/null
+++ b/config/user-nptl_guard_within_stack.m4
@@ -0,0 +1,56 @@
+dnl #
+dnl # Check if the glibc NPTL threading implementation includes the guard area
+dnl # within the stack size allocation, rather than allocating extra space at
+dnl # the end of the stack, as POSIX.1 requires.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_STACK_GUARD], [
+
+	AC_MSG_CHECKING([whether pthread stack includes guard])
+
+	saved_CFLAGS="$CFLAGS"
+	CFLAGS="-fstack-check"
+	saved_LDFLAGS="$LDFLAGS"
+	LDFLAGS="-lpthread"
+
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(
+	[
+		#include <pthread.h>
+		#include <sys/resource.h>
+		#include <unistd.h>
+		#include <bits/local_lim.h>
+
+		#define PAGESIZE (sysconf(_SC_PAGESIZE))
+		#define STACK_SIZE 8192
+		#define BUFSIZE 4096
+
+		void * func(void *arg)
+		{
+			char buf[[[BUFSIZE]]];
+		}
+	],
+	[
+		pthread_t tid;
+		pthread_attr_t attr;
+		struct rlimit l;
+
+		l.rlim_cur = 0;
+		l.rlim_max = 0;
+		setrlimit(RLIMIT_CORE, &l);
+		pthread_attr_init(&attr);
+		pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + STACK_SIZE);
+		pthread_attr_setguardsize(&attr, PAGESIZE);
+		pthread_create(&tid, &attr, func, NULL);
+		pthread_join(tid, NULL);
+	]),
+	[
+		AC_MSG_RESULT([no])
+	],
+	[
+		AC_DEFINE([NPTL_GUARD_WITHIN_STACK], 1,
+			[Define to 1 if NPTL threading implementation includes
+			guard area in stack allocation])
+		AC_MSG_RESULT([yes])
+	])
+	CFLAGS="$saved_CFLAGS"
+	LDFLAGS="$saved_LDFLAGS"
+])
diff --git a/config/user.m4 b/config/user.m4
index 2f9825ce0d..bc68808f80 100644
--- a/config/user.m4
+++ b/config/user.m4
@@ -9,4 +9,5 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
 	ZFS_AC_CONFIG_USER_LIBUUID
 	ZFS_AC_CONFIG_USER_LIBBLKID
 	ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
+	ZFS_AC_CONFIG_USER_STACK_GUARD
 ])
diff --git a/lib/libzpool/include/sys/zfs_context.h b/lib/libzpool/include/sys/zfs_context.h
index 329cc149c9..79fb3bb871 100644
--- a/lib/libzpool/include/sys/zfs_context.h
+++ b/lib/libzpool/include/sys/zfs_context.h
@@ -209,6 +209,12 @@ _NOTE(CONSTCOND) } while (0)
 #define	STACK_SIZE		24576	/* Solaris */
 #endif
 
+#ifdef NPTL_GUARD_WITHIN_STACK
+#define	EXTRA_GUARD_BYTES	PAGESIZE
+#else
+#define	EXTRA_GUARD_BYTES	0
+#endif
+
 /* in libzpool, p0 exists only to have its address taken */
 typedef struct proc {
 	uintptr_t	this_is_never_used_dont_dereference_it;
diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c
index a4252c6310..b657d124c3 100644
--- a/lib/libzpool/kernel.c
+++ b/lib/libzpool/kernel.c
@@ -162,8 +162,16 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
 	 * kernel space.  PTHREAD_STACK_MIN is the minimum stack
 	 * required for a NULL procedure in user space and is added
 	 * in to the stack requirements.
+	 *
+	 * Some buggy NPTL threading implementations include the
+	 * guard area within the stack size allocations.  In
+	 * this case we allocate an extra page to account for the
+	 * guard area since we only have two pages of usable stack
+	 * on Linux.
 	 */
-	stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE);
+
+	stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE) +
+			EXTRA_GUARD_BYTES;
 
 	VERIFY3S(pthread_attr_init(&attr), ==, 0);
 	VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);