diff --git a/auth.h b/auth.h
index 548e0174a7ba07c13e33687f040b5f3f87511b1e..6d6ebc7a7f956ca02a9f9ab23ecbcc9db81fb0d6 100644
--- a/auth.h
+++ b/auth.h
@@ -77,6 +77,9 @@ struct AuthState {
 	unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for
 							  client and server (though has differing [obvious]
 							  meanings). */
+	unsigned perm_warn : 1; /* Server only, set if bad permissions on 
+							   ~/.ssh/authorized_keys have already been
+							   logged. */
 
 	/* These are only used for the server */
 	char *printableuser; /* stripped of control chars, used for logs etc */
diff --git a/svr-authpubkey.c b/svr-authpubkey.c
index a5520e58b00d2d3997d58e8fe8d3e65c185e0f26..3942bd55ff8c217291cc02c7df3cd1e7c779c607 100644
--- a/svr-authpubkey.c
+++ b/svr-authpubkey.c
@@ -311,6 +311,7 @@ out:
 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 static int checkfileperm(char * filename) {
 	struct stat filestat;
+	int badperm = 0;
 
 	TRACE(("enter checkfileperm(%s)", filename))
 
@@ -321,14 +322,23 @@ static int checkfileperm(char * filename) {
 	/* check ownership - user or root only*/
 	if (filestat.st_uid != ses.authstate.pw->pw_uid
 			&& filestat.st_uid != 0) {
-		TRACE(("leave checkfileperm: wrong ownership"))
-		return DROPBEAR_FAILURE;
+		badperm = 1;
+		TRACE(("wrong ownership"))
 	}
 	/* check permissions - don't want group or others +w */
 	if (filestat.st_mode & (S_IWGRP | S_IWOTH)) {
-		TRACE(("leave checkfileperm: wrong perms"))
+		badperm = 1;
+		TRACE(("wrong perms"))
+	}
+	if (badperm) {
+		if (!ses.authstate.perm_warn) {
+			ses.authstate.perm_warn = 1;
+			dropbear_log(LOG_INFO, "%s must be owned by user or root, and not writable by others", filename);
+		}
+		TRACE(("leave checkfileperm: failure perms/owner"))
 		return DROPBEAR_FAILURE;
 	}
+
 	TRACE(("leave checkfileperm: success"))
 	return DROPBEAR_SUCCESS;
 }