diff --git a/g10/import.c b/g10/import.c
--- a/g10/import.c
+++ b/g10/import.c
@@ -1042,22 +1042,8 @@
       switch (pkt->pkttype)
         {
         case PKT_COMPRESSED:
-          if (check_compress_algo (pkt->pkt.compressed->algorithm))
-            {
-              rc = GPG_ERR_COMPR_ALGO;
-              goto ready;
-            }
-          else
-            {
-              compress_filter_context_t *cfx = xmalloc_clear( sizeof *cfx );
-              pkt->pkt.compressed->buf = NULL;
-              if (push_compress_filter2 (a, cfx,
-                                         pkt->pkt.compressed->algorithm, 1))
-                xfree (cfx); /* e.g. in case of compression_algo NONE.  */
-            }
-          free_packet (pkt, &parsectx);
-          init_packet(pkt);
-          break;
+          rc = GPG_ERR_UNEXPECTED;
+          goto ready;
 
         case PKT_RING_TRUST:
           /* Skip those packets unless we are in restore mode.  */
diff --git a/g10/mainproc.c b/g10/mainproc.c
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -152,6 +152,7 @@
 {
   kbnode_t node;
 
+  log_assert(!(c->sigs_only && c->signed_data.used));
   if (c->list) /* Add another packet. */
     add_kbnode (c->list, new_kbnode (pkt));
   else /* Insert the first one.  */
@@ -1077,7 +1078,10 @@
 
   /*printf("zip: compressed data packet\n");*/
   if (c->sigs_only)
-    rc = handle_compressed (c->ctrl, c, zd, proc_compressed_cb, c);
+    {
+      log_assert(!c->signed_data.used);
+      rc = handle_compressed (c->ctrl, c, zd, proc_compressed_cb, c);
+    }
   else if( c->encrypt_only )
     rc = handle_compressed (c->ctrl, c, zd, proc_encrypt_cb, c);
   else
@@ -1596,6 +1600,7 @@
   c->iobuf = a;
   init_packet(pkt);
   init_parse_packet (&parsectx, a);
+  parsectx.sigs_only = c->sigs_only && c->signed_data.used;
   while ((rc=parse_packet (&parsectx, pkt)) != -1)
     {
       any_data = 1;
@@ -1607,6 +1612,12 @@
           if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
               && opt.list_packets == 0)
             break;
+
+          if (gpg_err_code (rc) == GPG_ERR_UNEXPECTED)
+            {
+              write_status_text( STATUS_UNEXPECTED, "0" );
+              goto leave;
+            }
           continue;
 	}
       newpkt = -1;
@@ -1644,7 +1655,9 @@
             case PKT_COMPRESSED:  rc = proc_compressed (c, pkt); break;
             case PKT_ONEPASS_SIG: newpkt = add_onepass_sig (c, pkt); break;
             case PKT_GPG_CONTROL: newpkt = add_gpg_control (c, pkt); break;
-            default: newpkt = 0; break;
+            default:
+	      log_assert(!c->signed_data.used);
+	      newpkt = 0; break;
 	    }
 	}
       else if (c->encrypt_only)
diff --git a/g10/packet.h b/g10/packet.h
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -657,6 +657,7 @@
   int free_last_pkt; /* Indicates that LAST_PKT must be freed.  */
   int skip_meta;     /* Skip ring trust packets.  */
   unsigned int n_parsed_packets;	/* Number of parsed packets.  */
+  int sigs_only;     /* Only accept detached signature packets */
 };
 typedef struct parse_packet_ctx_s *parse_packet_ctx_t;
 
@@ -667,6 +668,7 @@
     (a)->free_last_pkt = 0;         \
     (a)->skip_meta = 0;             \
     (a)->n_parsed_packets = 0;      \
+    (a)->sigs_only = 0;             \
   } while (0)
 
 #define deinit_parse_packet(a) do { \
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -738,6 +738,20 @@
             case PKT_ENCRYPTED_MDC:
             case PKT_ENCRYPTED_AEAD:
             case PKT_COMPRESSED:
+              if (ctx->sigs_only)
+                {
+                  log_error (_("partial length packet of type %d in detached"
+                               " signature\n"), pkttype);
+                  rc = gpg_error (GPG_ERR_UNEXPECTED);
+                  goto leave;
+                }
+              if (onlykeypkts)
+                {
+                  log_error (_("partial length packet of type %d in keyring\n"),
+                             pkttype);
+                  rc = gpg_error (GPG_ERR_UNEXPECTED);
+                  goto leave;
+                }
               iobuf_set_partial_body_length_mode (inp, c & 0xff);
               pktlen = 0;	/* To indicate partial length.  */
               partial = 1;
@@ -775,6 +789,20 @@
 	      rc = gpg_error (GPG_ERR_INV_PACKET);
 	      goto leave;
 	    }
+	  else if (ctx->sigs_only)
+	    {
+	      log_error (_("indeterminate length packet of type %d in detached"
+                           " signature\n"), pkttype);
+	      rc = gpg_error (GPG_ERR_UNEXPECTED);
+	      goto leave;
+	    }
+	  else if (onlykeypkts)
+	    {
+	      log_error (_("indeterminate length packet of type %d in"
+                           " keyring\n"), pkttype);
+	      rc = gpg_error (GPG_ERR_UNEXPECTED);
+	      goto leave;
+	    }
 	}
       else
 	{
@@ -828,7 +856,21 @@
       goto leave;
     }
 
-  if (with_uid && pkttype == PKT_USER_ID)
+  if (ctx->sigs_only)
+    switch (pkttype)
+      {
+      case PKT_SIGNATURE:
+      case PKT_MARKER:
+	break;
+      default:
+        log_error(_("Packet type %d not allowed in detached signature\n"),
+                  pkttype);
+	iobuf_skip_rest (inp, pktlen, partial);
+	*skip = 1;
+	rc = GPG_ERR_UNEXPECTED;
+	goto leave;
+      }
+  else if (with_uid && pkttype == PKT_USER_ID)
     /* If ONLYKEYPKTS is set to 2, then we never skip user id packets,
        even if DO_SKIP is set.  */
     ;