diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -300,7 +300,8 @@
 HADOLINT_IGNORE=DL3010,DL3020            # comma separated list of rule codes
 HADOLINT_STRICT_LABELS=1                 # Truthy value e.g. 1, true or yes
 HADOLINT_DISABLE_IGNORE_PRAGMA=1         # Truthy value e.g. 1, true or yes
-HADOLINT_TRUSTED_REGISTRIES              # comma separated list of registry urls
+HADOLINT_TRUSTED_REGISTRIES=docker.io    # comma separated list of registry urls
+HADOLINT_REQUIRE_LABELS=maintainer:text  # comma separated list of label schema items
 ```
 
 ## Non-Posix Shells
diff --git a/hadolint.cabal b/hadolint.cabal
--- a/hadolint.cabal
+++ b/hadolint.cabal
@@ -1,11 +1,11 @@
 cabal-version: 2.0
 
--- This file has been generated from package.yaml by hpack version 0.34.4.
+-- This file has been generated from package.yaml by hpack version 0.34.6.
 --
 -- see: https://github.com/sol/hpack
 
 name:           hadolint
-version:        2.10.0
+version:        2.11.0
 synopsis:       Dockerfile Linter JavaScript API
 description:    A smarter Dockerfile linter that helps you build best practice Docker images.
 category:       Development
@@ -155,7 +155,7 @@
     , foldl
     , gitrev >=1.3.1
     , ilist
-    , language-docker >=10.4.3 && <11
+    , language-docker >=11.0.0 && <12
     , megaparsec >=9.0.0
     , mtl
     , network-uri
@@ -176,6 +176,8 @@
   main-is: Main.hs
   other-modules:
       Paths_hadolint
+  autogen-modules:
+      Paths_hadolint
   hs-source-dirs:
       app
   default-extensions:
@@ -195,7 +197,7 @@
     , containers
     , data-default
     , hadolint
-    , language-docker >=10.4.3 && <11
+    , language-docker >=11.0.0 && <12
     , megaparsec >=9.0.0
     , optparse-applicative >=0.14.0
     , prettyprinter >=1.7.0
@@ -289,6 +291,8 @@
       Helpers
       RegressionSpec
       Paths_hadolint
+  autogen-modules:
+      Paths_hadolint
   hs-source-dirs:
       test
   default-extensions:
@@ -317,7 +321,7 @@
     , foldl
     , hadolint
     , hspec >=2.8.3
-    , language-docker >=10.4.3 && <11
+    , language-docker >=11.0.0 && <12
     , megaparsec >=9.0.0
     , optparse-applicative >=0.14.0
     , silently
diff --git a/src/Hadolint/Config/Configuration.hs b/src/Hadolint/Config/Configuration.hs
--- a/src/Hadolint/Config/Configuration.hs
+++ b/src/Hadolint/Config/Configuration.hs
@@ -192,7 +192,7 @@
     partialNoFail <- m .:? "no-fail" .!= Nothing
     partialNoColor <- m .:? "no-color" .!= Nothing
     partialVerbose <- m .:? "verbose" .!= Nothing
-    partialFormat <- m .:? "output-format"
+    partialFormat <- m .:? "format"
     override <- m .:? "override" .!= mempty
     ignored <- m .:? "ignored" .!= mempty
     trusted <- m .:? "trustedRegistries" .!= mempty
diff --git a/src/Hadolint/Rule/DL3010.hs b/src/Hadolint/Rule/DL3010.hs
--- a/src/Hadolint/Rule/DL3010.hs
+++ b/src/Hadolint/Rule/DL3010.hs
@@ -26,7 +26,7 @@
     message = "Use `ADD` for extracting archives into an image"
 
     check _ _ (From _) = emptyState Empty
-    check line st (Copy (CopyArgs srcs tgt _ _ NoSource)) =
+    check line st (Copy (CopyArgs srcs tgt) (CopyFlags _ _ _ NoSource)) =
       st |> modify (rememberArchives line srcs tgt)
     check _ st (Run (RunArgs args _))
       | Acc archives _ <- state st,
diff --git a/src/Hadolint/Rule/DL3013.hs b/src/Hadolint/Rule/DL3013.hs
--- a/src/Hadolint/Rule/DL3013.hs
+++ b/src/Hadolint/Rule/DL3013.hs
@@ -44,12 +44,18 @@
         || ["."] `isInfixOf` Shell.getArgs cmd
 
     hasBuildConstraint cmd = Shell.hasFlag "constraint" cmd || Shell.hasFlag "c" cmd
-    versionFixed package = hasVersionSymbol package || isVersionedGit package || isLocalPackage package
-    isVersionedGit package = "git+http" `Text.isInfixOf` package && "@" `Text.isInfixOf` package
+    versionFixed package = hasVersionSymbol package
+      || isVersionedVcs package
+      || isLocalPackage package
+      || isNoVcsPathSource package
+    isVersionedVcs package = isVcs package
+      && "@" `Text.isInfixOf` package
     versionSymbols = ["==", ">=", "<=", ">", "<", "!=", "~=", "==="]
     hasVersionSymbol package = or [s `Text.isInfixOf` package | s <- versionSymbols]
     localPackageFileExtensions = [".whl", ".tar.gz"]
     isLocalPackage package = or [s `Text.isSuffixOf` package | s <- localPackageFileExtensions]
+    isNoVcsPathSource package = not (isVcs package) && "/" `Text.isInfixOf` package
+    isVcs package = any (`Text.isPrefixOf` package) vcsSchemes
 {-# INLINEABLE dl3013 #-}
 
 packages :: Shell.Command -> [Text.Text]
@@ -83,6 +89,35 @@
           "upgrade-strategy"
         ]
         cmd
+
+-- Supported schemes vcs[+protocol] are found here:
+-- https://pip.pypa.io/en/stable/topics/vcs-support/
+vcsSchemes :: [Text.Text]
+vcsSchemes =
+  [
+    "git+file",
+    "git+https",
+    "git+ssh",
+    "git+http",
+    "git+git",
+    "git",
+    "hg+file",
+    "hg+http",
+    "hg+https",
+    "hg+ssh",
+    "hg+static-http",
+    "svn",
+    "svn+svn",
+    "svn+http",
+    "svn+https",
+    "svn+ssh",
+    "bzr+http",
+    "bzr+https",
+    "bzr+ssh",
+    "bzr+sftp",
+    "bzr+ftp",
+    "bzr+lp"
+  ]
 
 stripInstallPrefix :: [Text.Text] -> [Text.Text]
 stripInstallPrefix cmd = dropWhile (== "install") (dropWhile (/= "install") cmd)
diff --git a/src/Hadolint/Rule/DL3020.hs b/src/Hadolint/Rule/DL3020.hs
--- a/src/Hadolint/Rule/DL3020.hs
+++ b/src/Hadolint/Rule/DL3020.hs
@@ -12,7 +12,7 @@
     severity = DLErrorC
     message = "Use COPY instead of ADD for files and folders"
 
-    check (Add (AddArgs srcs _ _ _)) =
+    check (Add (AddArgs srcs _) _) =
       and [isArchive src || isUrl src | SourcePath src <- toList srcs]
     check _ = True
 {-# INLINEABLE rule #-}
diff --git a/src/Hadolint/Rule/DL3021.hs b/src/Hadolint/Rule/DL3021.hs
--- a/src/Hadolint/Rule/DL3021.hs
+++ b/src/Hadolint/Rule/DL3021.hs
@@ -11,7 +11,7 @@
     severity = DLErrorC
     message = "COPY with more than 2 arguments requires the last argument to end with /"
 
-    check (Copy (CopyArgs sources t _ _ _))
+    check (Copy (CopyArgs sources t) _)
       | length sources > 1 = endsWithSlash t
       | otherwise = True
     check _ = True
diff --git a/src/Hadolint/Rule/DL3022.hs b/src/Hadolint/Rule/DL3022.hs
--- a/src/Hadolint/Rule/DL3022.hs
+++ b/src/Hadolint/Rule/DL3022.hs
@@ -1,6 +1,7 @@
 module Hadolint.Rule.DL3022 (rule) where
 
 import qualified Data.Set as Set
+import qualified Data.Text as Text
 import Hadolint.Rule
 import Language.Docker.Syntax
 
@@ -12,7 +13,8 @@
     message = "`COPY --from` should reference a previously defined `FROM` alias"
 
     check _ st (From BaseImage {alias = Just (ImageAlias als)}) = st |> modify (Set.insert als)
-    check line st (Copy (CopyArgs _ _ _ _ (CopySource s)))
+    check line st (Copy (CopyArgs _ _) (CopyFlags _ _ _ (CopySource s)))
+      | ":" `Text.isInfixOf` dropQuotes s = st
       | Set.member s (state st) = st
       | otherwise = st |> addFail CheckFailure {..}
     check _ st _ = st
diff --git a/src/Hadolint/Rule/DL3023.hs b/src/Hadolint/Rule/DL3023.hs
--- a/src/Hadolint/Rule/DL3023.hs
+++ b/src/Hadolint/Rule/DL3023.hs
@@ -11,7 +11,7 @@
     message = "`COPY --from` cannot reference its own `FROM` alias"
 
     check _ st f@(From _) = st |> replaceWith (Just f) -- Remember the last FROM instruction found
-    check line st@(State _ (Just fromInstr)) (Copy (CopyArgs _ _ _ _ (CopySource stageName)))
+    check line st@(State _ (Just fromInstr)) (Copy (CopyArgs _ _) (CopyFlags _ _ _ (CopySource stageName)))
       | aliasMustBe (/= stageName) fromInstr = st
       | otherwise = st |> addFail CheckFailure {..}
     -- cannot copy from the same stage!
diff --git a/src/Hadolint/Rule/DL3045.hs b/src/Hadolint/Rule/DL3045.hs
--- a/src/Hadolint/Rule/DL3045.hs
+++ b/src/Hadolint/Rule/DL3045.hs
@@ -32,7 +32,7 @@
 
     check _ st (From from) = st |> modify (rememberStage from)
     check _ st (Workdir _) = st |> modify rememberWorkdir
-    check line st (Copy (CopyArgs _ (TargetPath dest) _ _ _))
+    check line st (Copy (CopyArgs _ (TargetPath dest)) _)
       | Acc s m <- state st, Just True <- Map.lookup s m = st -- workdir has been set
       | "/" `Text.isPrefixOf` Text.dropAround quotePredicate dest = st -- absolute dest. normal
       | isWindowsAbsolute (Text.dropAround quotePredicate dest) = st -- absolute dest. windows
diff --git a/src/Hadolint/Rule/DL3049.hs b/src/Hadolint/Rule/DL3049.hs
--- a/src/Hadolint/Rule/DL3049.hs
+++ b/src/Hadolint/Rule/DL3049.hs
@@ -1,4 +1,4 @@
- module Hadolint.Rule.DL3049 (rule) where
+module Hadolint.Rule.DL3049 (rule) where
 
 import qualified Data.Map as Map
 import qualified Data.Set as Set
@@ -12,16 +12,18 @@
 rule labelschema = mconcat $ fmap missingLabelRule (Map.keys labelschema)
 {-# INLINEABLE rule #-}
 
+
 data StageID = StageID
-  { name :: Text.Text,
+  { name :: BaseImage,
     line :: Linenumber
   } deriving (Eq, Ord, Show)
 
 data Acc
-  = Acc StageID (Set.Set StageID) (Set.Set StageID)
+  = Acc StageID (Set.Set StageID) (Set.Set StageID) (Set.Set StageID)
   | Empty
   deriving (Show)
 
+
 -- missingLabelRule
 --
 -- triggers on a `FROM` instruction when label `label` is not defined within
@@ -32,29 +34,52 @@
     code = "DL3049"
     severity = DLInfoC
     message = "Label `" <> label <> "` is missing."
-    check line state (From BaseImage {image, alias = Just als}) =
-        state |> modify (currentStage (imageName image) (StageID (unImageAlias als) line))
-    check line state (From BaseImage {image, alias = Nothing}) =
-        state |> modify (currentStage (imageName image) (StageID (imageName image) line))
+    check line state (From img) =
+      state |> modify (currentStage (StageID img line))
+    check _ state (Copy (CopyArgs _ _) (CopyFlags _ _ _ (CopySource src))) =
+      state |> modify (markSilentByAlias src)
     check _ state (Label pairs)
-        | label `elem` fmap fst pairs = state |> modify goodStage
-        | otherwise = state
+      | label `elem` fmap fst pairs =
+          state
+            |> modify (markSilentByAlias (getCurrentStageName state))
+            |> modify markGood
+      | otherwise = state
     check _ state _ = state
 
     markFailure :: State Acc -> Failures
-    markFailure (State fails (Acc _ _ b)) = Set.foldl' (Seq.|>) fails (Set.map markFail b)
+    markFailure (State fails (Acc _ _ _ b)) = Set.foldl' (Seq.|>) fails (Set.map markFail b)
     markFailure st = failures st
 
     markFail (StageID _ line) = CheckFailure {..}
 
-currentStage :: Text.Text -> StageID -> Acc -> Acc
-currentStage src stageid (Acc _ g b)
-    | not $ Set.null (Set.filter (predicate src) g) = Acc stageid (g |> Set.insert stageid) b
-    | otherwise = Acc stageid g (b |> Set.insert stageid)
+
+currentStage :: StageID -> Acc -> Acc
+currentStage stageid Empty = Acc stageid Set.empty Set.empty (Set.singleton stageid)
+currentStage stageid (Acc _ g s b)
+  | not $ Set.null (Set.filter (predicate stageid) g) =
+      Acc stageid (g |> Set.insert stageid) s b
+  | otherwise = Acc stageid g s (b |> Set.insert stageid)
   where
-    predicate n0 StageID {name = n1} = n1 == n0
-currentStage _ stageid Empty = Acc stageid Set.empty (Set.singleton stageid)
+    predicate (StageID _ _) (StageID BaseImage {alias = Nothing} _) = False
+    predicate (StageID BaseImage {image} _) (StageID BaseImage {alias = Just als} _) =
+      unImageAlias als == imageName image
 
-goodStage :: Acc -> Acc
-goodStage (Acc stageid g b) = Acc stageid (g |> Set.insert stageid) (b |> Set.delete stageid)
-goodStage Empty = Empty
+markGood :: Acc -> Acc
+markGood Empty = Empty
+markGood (Acc stageid good silent bad) =
+  Acc stageid (good |> Set.insert stageid) (silent |> Set.delete stageid) (bad |> Set.delete stageid)
+
+markSilentByAlias :: Text.Text -> Acc -> Acc
+markSilentByAlias _ Empty = Empty
+markSilentByAlias silentname (Acc stageid good silent bad) =
+  Acc stageid good (silent |> Set.union stages) (bad |> remove stages)
+  where
+    stages = Set.filter byName bad
+    byName (StageID BaseImage {alias = Nothing} _) = False
+    byName (StageID BaseImage {alias = Just als} _) = unImageAlias als == silentname
+    remove set fromThis = Set.difference fromThis set
+
+getCurrentStageName :: State Acc -> Text.Text
+getCurrentStageName (State _ (Acc (StageID BaseImage {image, alias = Nothing} _) _ _ _)) = imageName image
+getCurrentStageName (State _ (Acc (StageID BaseImage {alias = Just als} _) _ _ _)) = unImageAlias als
+getCurrentStageName _ = ""
diff --git a/src/Hadolint/Rule/DL3057.hs b/src/Hadolint/Rule/DL3057.hs
--- a/src/Hadolint/Rule/DL3057.hs
+++ b/src/Hadolint/Rule/DL3057.hs
@@ -8,7 +8,8 @@
 
 
 data StageID = StageID
-  { name :: Text.Text,
+  { src :: Text.Text,
+    name :: Text.Text,
     line :: Linenumber
   } deriving (Show, Eq, Ord)
 
@@ -25,16 +26,24 @@
     message = "`HEALTHCHECK` instruction missing."
 
     check line state (From BaseImage {image, alias = Just als}) =
-      state |> modify (currentStage (imageName image) (StageID (unImageAlias als) line))
+      state |> modify
+                  ( currentStage
+                      (imageName image)
+                      (StageID (imageName image) (unImageAlias als) line)
+                  )
     check line state (From BaseImage {image, alias = Nothing}) =
-      state |> modify (currentStage (imageName image) (StageID (imageName image) line))
+      state |> modify
+                  ( currentStage
+                      (imageName image)
+                      (StageID (imageName image) (imageName image) line)
+                  )
     check _ state (Healthcheck _) = state |> modify goodStage
     check _ state _ = state
 
     markFailures :: State Acc -> Failures
     markFailures (State fails (Acc _ _ b)) = Set.foldl' (Seq.|>) fails (Set.map makeFail b)
     markFailures st = failures st
-    makeFail (StageID _ line) = CheckFailure {..}
+    makeFail (StageID _ _ line) = CheckFailure {..}
 {-# INLINEABLE rule #-}
 
 currentStage :: Text.Text -> StageID -> Acc -> Acc
@@ -46,5 +55,29 @@
 currentStage _ stageid Empty = Acc stageid Set.empty (Set.singleton stageid)
 
 goodStage :: Acc -> Acc
-goodStage (Acc stageid g b) = Acc stageid (g |> Set.insert stageid) (b |> Set.delete stageid)
+goodStage (Acc stageid g b) = do
+  let nowGood = recurseGood b stageid
+  let good =
+        g
+          |> Set.union nowGood
+          |> Set.insert stageid
+      bad =
+        b
+          |> flip Set.difference nowGood
+          |> Set.delete stageid
+   in Acc
+        stageid
+        good
+        bad
+  where
+    predicate StageID { src = s1 } StageID { name = n1 } = n1 == s1
+
+    recurseGood :: Set.Set StageID -> StageID -> Set.Set StageID
+    recurseGood bad sid = do
+      let g1 = Set.filter (predicate sid) bad  -- bad stages to be marked good
+          b1 = Set.difference bad g1  -- bad stages not to be marked good
+       in if Set.null g1
+            then g1
+            else Set.union g1 $ Set.unions $ Set.map (recurseGood b1) g1
+
 goodStage Empty = Empty
diff --git a/test/Hadolint/Config/ConfigfileSpec.hs b/test/Hadolint/Config/ConfigfileSpec.hs
--- a/test/Hadolint/Config/ConfigfileSpec.hs
+++ b/test/Hadolint/Config/ConfigfileSpec.hs
@@ -46,13 +46,13 @@
           conf = parseYaml yaml
       conf `shouldBe` Right mempty { partialVerbose = Just False }
 
-    it "parse `output-format: json`" $ do
-      let yaml = ["output-format: json"]
+    it "parse `format: json`" $ do
+      let yaml = ["format: json"]
           conf = parseYaml yaml
       conf `shouldBe` Right mempty { partialFormat = Just Json }
 
-    it "parse `output-format: sarif`" $ do
-      let yaml = ["output-format: sarif"]
+    it "parse `format: sarif`" $ do
+      let yaml = ["format: sarif"]
           conf = parseYaml yaml
       conf `shouldBe` Right mempty { partialFormat = Just Sarif }
 
diff --git a/test/Hadolint/Config/EnvironmentSpec.hs b/test/Hadolint/Config/EnvironmentSpec.hs
--- a/test/Hadolint/Config/EnvironmentSpec.hs
+++ b/test/Hadolint/Config/EnvironmentSpec.hs
@@ -210,6 +210,7 @@
   unsetEnv "HADOLINT_REQUIRE_LABELS"
   unsetEnv "HADOLINT_STRICT_LABELS"
   unsetEnv "HADOLINT_FAILURE_THRESHOLD"
+  unsetEnv "HADOLINT_DISABLE_IGNORE_PRAGMA"
 
 -- On Windows setting an environment variable to the empty string is the same as
 -- unsetting it. On POSIX, an environment variable can be set and contain the
diff --git a/test/Hadolint/Rule/DL3013Spec.hs b/test/Hadolint/Rule/DL3013Spec.hs
--- a/test/Hadolint/Rule/DL3013Spec.hs
+++ b/test/Hadolint/Rule/DL3013Spec.hs
@@ -76,6 +76,12 @@
       onBuildRuleCatchesNot
         "DL3013"
         "RUN pip install git+https://github.com/rtfd/r-ext.git@0.6-alpha#egg=r-ext"
+      ruleCatchesNot
+        "DL3013"
+        "RUN pip install git+ssh://github.com/rtfd/r-ext.git@0.6-alpha#egg=r-ext"
+      onBuildRuleCatchesNot
+        "DL3013"
+        "RUN pip install git+ssh://github.com/rtfd/r-ext.git@0.6-alpha#egg=r-ext"
     it "pip install unversioned git" $ do
       ruleCatches
         "DL3013"
@@ -83,6 +89,26 @@
       onBuildRuleCatches
         "DL3013"
         "RUN pip install git+https://github.com/rtfd/read-ext.git#egg=read-ext"
+      ruleCatches
+        "DL3013"
+        "RUN pip install git+ssh://github.com/rtfd/read-ext.git#egg=read-ext"
+      onBuildRuleCatches
+        "DL3013"
+        "RUN pip install git+ssh://github.com/rtfd/read-ext.git#egg=read-ext"
+    it "pip install local dir" $ do
+      ruleCatchesNot
+        "DL3013"
+        "RUN pip install foo/bar"
+      onBuildRuleCatchesNot
+        "DL3013"
+        "RUN pip install foo/bar"
+    it "pip install https url package" $ do
+      ruleCatchesNot
+        "DL3013"
+        "RUN pip install https://foo.bar/baz.zip"
+      onBuildRuleCatchesNot
+        "DL3013"
+        "RUN pip install https://foo.bar/baz.zip"
     it "pip install upper bound" $ do
       ruleCatchesNot "DL3013" "RUN pip install 'alabaster>=0.7'"
       onBuildRuleCatchesNot "DL3013" "RUN pip install 'alabaster>=0.7'"
diff --git a/test/Hadolint/Rule/DL3022Spec.hs b/test/Hadolint/Rule/DL3022Spec.hs
--- a/test/Hadolint/Rule/DL3022Spec.hs
+++ b/test/Hadolint/Rule/DL3022Spec.hs
@@ -29,3 +29,4 @@
               "RUN baz"
             ]
        in ruleCatchesNot "DL3022" $ Text.unlines dockerFile
+    it "don't warn on external images" $ ruleCatchesNot "DL3022" "COPY --from=haskell:latest bar ."
diff --git a/test/Hadolint/Rule/DL3026Spec.hs b/test/Hadolint/Rule/DL3026Spec.hs
--- a/test/Hadolint/Rule/DL3026Spec.hs
+++ b/test/Hadolint/Rule/DL3026Spec.hs
@@ -11,7 +11,7 @@
 spec = do
   let ?config = def
 
-  describe "DL2036 - Use only an allowed registry in the FROM image" $ do
+  describe "DL3026 - Use only an allowed registry in the FROM image" $ do
     it "does not warn on empty allowed registries" $ do
       let dockerFile =
             [ "FROM random.com/debian"
diff --git a/test/Hadolint/Rule/DL3049Spec.hs b/test/Hadolint/Rule/DL3049Spec.hs
--- a/test/Hadolint/Rule/DL3049Spec.hs
+++ b/test/Hadolint/Rule/DL3049Spec.hs
@@ -43,6 +43,15 @@
        in assertChecks
             (Text.unlines dockerFile)
             (failsWith 2 "DL3049")
+    it "warn once: two stages, label present in first only" $
+      let dockerFile =
+            [ "FROM baseimage",
+              "LABEL foo=\"bar\"",
+              "FROM newimage"
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 1 "DL3049")
     it "warn once: two stages, label present in second only" $
       let dockerFile =
             [ "FROM baseimage",
@@ -62,14 +71,41 @@
        in assertChecks
             (Text.unlines dockerFile)
             (failsWith 1 "DL3049")
-    it "warn once: two stages, inheritance, label only defined in second stage" $
+    it "warn twice: two stages, inheritance, no labels" $
       let dockerFile =
             [ "FROM baseimage as base",
+              "FROM base"
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 2 "DL3049")
+    it "don't warn: two stages, inheritance, label defined in second stage" $
+      let dockerFile =
+            [ "FROM baseimage as base",
               "FROM base",
               "LABEL foo=\"bar\""
             ]
        in assertChecks
             (Text.unlines dockerFile)
+            (failsWith 0 "DL3049")
+    it "don't warn: two stages, no inheritance, label in last stage, with copy" $
+      let dockerFile =
+            [ "FROM baseimage as base",
+              "FROM anotherimage",
+              "LABEL foo=\"bar\"",
+              "COPY --from=base /bar /baz"
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 0 "DL3049")
+    it "warn once: two stages, no inheritance, label in last stage, no connection" $
+      let dockerFile =
+            [ "FROM baseimage as base",
+              "FROM anotherimage",
+              "LABEL foo=\"bar\""
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
             (failsWith 1 "DL3049")
     it "don't warn: two stages, inheritance" $
       let dockerFile =
@@ -80,3 +116,38 @@
        in assertChecks
             (Text.unlines dockerFile)
             (failsWith 0 "DL3049")
+    it "warn once: multiple results, no inheritance, label in one result" $
+      let dockerFile =
+            [ "FROM baseimage as base",
+              "FROM newimage",
+              "LABEL foo=\"bar\"",
+              "COPY --from=base /bar /baz",
+              "",
+              "FROM newimage",
+              "COPY --from=base /bar /baz"
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 1 "DL3049")
+    it "warn once: multiple results, inheritance, label in one result" $
+      let dockerFile =
+            [ "FROM baseimage as base",
+              "FROM base",
+              "LABEL foo=\"bar\"",
+              "",
+              "FROM base"
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 1 "DL3049")
+    it "warn once: multiple results, inheritance, label in one result" $
+      let dockerFile =
+            [ "FROM baseimage as base",
+              "FROM base",
+              "",
+              "FROM base",
+              "LABEL foo=\"bar\""
+            ]
+       in assertChecks
+            (Text.unlines dockerFile)
+            (failsWith 1 "DL3049")
diff --git a/test/Hadolint/Rule/DL3057Spec.hs b/test/Hadolint/Rule/DL3057Spec.hs
--- a/test/Hadolint/Rule/DL3057Spec.hs
+++ b/test/Hadolint/Rule/DL3057Spec.hs
@@ -1,6 +1,7 @@
 module Hadolint.Rule.DL3057Spec (spec) where
 
 import Data.Default
+import Data.Text as Text
 import Helpers
 import Test.Hspec
 
@@ -10,11 +11,63 @@
   let ?config = def
 
   describe "DL3057 - `HEALTHCHECK instruction missing" $ do
-    it "warn with no HEALTHCHECK instructions" $
-      ruleCatches "DL3057" "FROM scratch"
-    it "ok with one HEALTHCHECK instruction" $
-      ruleCatchesNot "DL3057" "FROM scratch\nHEALTHCHECK CMD /bin/bla"
-    it "ok with inheriting HEALTHCHECK instruction" $
-      ruleCatchesNot "DL3057" "FROM scratch AS base\nHEALTHCHECK CMD /bin/bla\nFROM base"
-    it "warn when not inheriting with no HEALTHCHECK instruction" $
-      ruleCatches "DL3057" "FROM scratch AS base\nHEALTHCHECK CMD /bin/bla\nFROM scratch"
+
+    it "warn with no HEALTHCHECK instructions" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch"
+            ]
+       in ruleCatches "DL3057" dockerfile
+
+    it "ok when HEALTHCHECK is explicitly disabled" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch",
+              "HEALTHCHECK NONE"
+            ]
+       in ruleCatchesNot "DL3057" dockerfile
+
+    it "ok with one HEALTHCHECK instruction" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch",
+              "HEALTHCHECK CMD /bin/bla"
+            ]
+       in ruleCatchesNot "DL3057" dockerfile
+
+    it "ok with inheriting HEALTHCHECK instruction" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch AS base",
+              "HEALTHCHECK CMD /bin/bla",
+              "FROM base"
+            ]
+       in ruleCatchesNot "DL3057" dockerfile
+
+    it "ok with ending inheritance chain with HEALTCHECK" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch AS base1",
+              "FROM base1 AS base2",
+              "FROM base2 AS base3",
+              "FROM base3 AS end",
+              "HEALTHCHECK NONE"
+            ]
+       in ruleCatchesNot "DL3057" dockerfile
+
+    it "warn when inheritance chain bifurcates" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch AS base1",
+              "FROM base1 AS base2",
+              "FROM base2 AS base3.1",
+              "FROM base2 AS base3.2",  -- This will trigger DL3057
+              "",
+              "FROM base3.1 AS end1",
+              "HEALTHCHECK NONE",
+              "",
+              "FROM base3.2 AS end2"  -- This will trigger DL3057
+            ]
+       in ruleCatches "DL3057" dockerfile
+
+    it "warn when not inheriting with no HEALTHCHECK instruction" $ do
+      let dockerfile = Text.unlines
+            [ "FROM scratch AS base",
+              "HEALTHCHECK CMD /bin/bla",
+              "FROM scratch"
+            ]
+       in ruleCatches "DL3057" dockerfile
