diff --git a/control.go b/control.go
index 6717acd8..d89d37d4 100644
--- a/control.go
+++ b/control.go
@@ -1050,6 +1050,20 @@ func handleTLSStatus(w http.ResponseWriter, r *http.Request) {
 	}
 }
 
+func handleTLSValidate(w http.ResponseWriter, r *http.Request) {
+	data, err := unmarshalTLS(r)
+	if err != nil {
+		httpError(w, http.StatusBadRequest, "Failed to unmarshal TLS config: %s", err)
+		return
+	}
+
+	data, err = validateCertificates(data)
+	if err != nil {
+		httpError(w, http.StatusBadRequest, "New TLS configuration does not validate: %s", err)
+		return
+	}
+}
+
 func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
 	data, err := unmarshalTLS(r)
 	if err != nil {
@@ -1057,14 +1071,25 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	data, err = validateCertificates(data)
+	if err != nil {
+		httpError(w, http.StatusBadRequest, "New TLS configuration does not validate: %s", err)
+		return
+	}
+	config.TLS = data
+	httpUpdateConfigReloadDNSReturnOK(w, r)
+}
+
+func validateCertificates(data tlsConfig) (tlsConfig, error) {
+	var err error
+
 	if data.CertificateChain != "" {
 		log.Printf("got certificate: %s", data.CertificateChain)
 
 		if data.PrivateKey != "" {
 			_, err = tls.X509KeyPair([]byte(data.CertificateChain), []byte(data.PrivateKey))
 			if err != nil {
-				httpError(w, http.StatusBadRequest, "Invalid certificate or key: %s", err)
-				return
+				return data, errorx.Decorate(err, "Invalid certificate or key")
 			}
 		}
 
@@ -1091,15 +1116,13 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
 		for _, cert := range certs {
 			parsed, err := x509.ParseCertificate(cert.Bytes)
 			if err != nil {
-				httpError(w, http.StatusBadRequest, "failed to parse certificate: %s", err)
-				return
+				return data, errorx.Decorate(err, "Failed to parse certificate")
 			}
 			parsedCerts = append(parsedCerts, parsed)
 		}
 
 		if len(parsedCerts) == 0 {
-			httpError(w, http.StatusBadRequest, "You have specified an empty certificate")
-			return
+			return data, fmt.Errorf("You have specified an empty certificate")
 		}
 
 		// spew.Dump(parsedCerts)
@@ -1121,11 +1144,10 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
 
 		// TODO: save it as a warning rather than error it out -- shouldn't be a big problem
 		mainCert := parsedCerts[0]
-		_, err = mainCert.Verify(opts)
+		_, err := mainCert.Verify(opts)
 		if err != nil {
 			// TODO: let self-signed certs through
-			httpError(w, http.StatusBadRequest, "Your certificate does not verify: %s", err)
-			return
+			return data, errorx.Decorate(err, "Your certificate does not verify")
 		}
 		// spew.Dump(chains)
 
@@ -1151,8 +1173,7 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	config.TLS = data
-	httpUpdateConfigReloadDNSReturnOK(w, r)
+	return data, nil
 }
 
 // unmarshalTLS handles base64-encoded certificates transparently
@@ -1232,4 +1253,5 @@ func registerControlHandlers() {
 
 	http.HandleFunc("/control/tls/status", postInstall(optionalAuth(ensureGET(handleTLSStatus))))
 	http.HandleFunc("/control/tls/configure", postInstall(optionalAuth(ensurePOST(handleTLSConfigure))))
+	http.HandleFunc("/control/tls/validate", postInstall(optionalAuth(ensurePOST(handleTLSValidate))))
 }