diff --git a/rio_cogeo/cogeo.py b/rio_cogeo/cogeo.py
index 8f2a551..c6f158e 100644
--- a/rio_cogeo/cogeo.py
+++ b/rio_cogeo/cogeo.py
@@ -6,7 +6,7 @@ import sys
 import tempfile
 import warnings
 from contextlib import ExitStack, contextmanager
-from typing import Any, Dict
+from typing import Any, Dict, List, Tuple
 
 import click
 import rasterio
@@ -288,7 +288,9 @@ def cog_translate(
                 copy(tmp_dst, dst_path, copy_src_overviews=True, **dst_kwargs)
 
 
-def cog_validate(src_path: str, strict: bool = False, quiet: bool = False):
+def cog_validate(
+    src_path: str, strict: bool = False, quiet: bool = False
+) -> Tuple[bool, List[str], List[str]]:
     """
     Validate Cloud Optimized Geotiff.
 
@@ -300,6 +302,8 @@ def cog_validate(src_path: str, strict: bool = False, quiet: bool = False):
         Treat warnings as errors
     quiet: bool
         Remove standard outputs
+    return_errors: bool
+        Return errors and warnings
 
     This script is the rasterio equivalent of
     https://svn.osgeo.org/gdal/trunk/gdal/swig/python/samples/validate_cloud_optimized_geotiff.py
@@ -446,7 +450,6 @@ def cog_validate(src_path: str, strict: bool = False, quiet: bool = False):
         for e in errors:
             click.echo("- " + e, err=True)
 
-    if errors or (warnings and strict):
-        return False
+    is_valid = False if errors or (warnings and strict) else True
 
-    return True
+    return is_valid, errors, warnings
diff --git a/rio_cogeo/scripts/cli.py b/rio_cogeo/scripts/cli.py
index c40979b..f8708df 100644
--- a/rio_cogeo/scripts/cli.py
+++ b/rio_cogeo/scripts/cli.py
@@ -253,7 +253,8 @@ def create(
 @click.option("--strict", default=False, is_flag=True, help="Treat warnings as errors.")
 def validate(input, strict):
     """Validate Cloud Optimized Geotiff."""
-    if cog_validate(input, strict=strict):
+    is_valid, _, _ = cog_validate(input, strict=strict)
+    if is_valid:
         click.echo("{} is a valid cloud optimized GeoTIFF".format(input))
     else:
         click.echo("{} is NOT a valid cloud optimized GeoTIFF".format(input))

cog_validate should return warnings and errors
In order to use `cog_validate` in other APIs I think it will be good to make it return the info instead of printing them 👇 

https://github.com/cogeotiff/rio-cogeo/blob/6fda1dc1904ea9317c776e709677af2cb2a698f6/rio_cogeo/cogeo.py#L438-L452
diff --git a/tests/test_validate.py b/tests/test_validate.py
index 791fb04..c670564 100644
--- a/tests/test_validate.py
+++ b/tests/test_validate.py
@@ -34,28 +34,40 @@ jpeg_profile.update({"blockxsize": 256, "blockysize": 256})
 def test_cog_validate_valid(monkeypatch):
     """Should work as expected (validate cogeo file)."""
     # not tiled but 512x512
-    assert cog_validate(raster_rgb)
+    assert cog_validate(raster_rgb)[0]
 
     # not tiled, no overview
-    assert not cog_validate(raster_big, quiet=True)
+    assert not cog_validate(raster_big, quiet=True)[0]
 
     # external overview
-    assert not cog_validate(raster_external)
+    assert not cog_validate(raster_external)[0]
 
     # non-sorted overview
-    assert not cog_validate(raster_ovrsorted)
+    assert not cog_validate(raster_ovrsorted)[0]
 
     # invalid decimation
-    assert not cog_validate(raster_decim)
+    assert not cog_validate(raster_decim)[0]
 
     # no overview
-    assert cog_validate(raster_no_ovr)
-    assert not cog_validate(raster_no_ovr, strict=True)
+    assert cog_validate(raster_no_ovr)[0]
+    assert not cog_validate(raster_no_ovr, strict=True)[0]
 
     with pytest.raises(Exception):
         cog_validate(raster_jpeg)
 
 
+def test_cog_validate_return():
+    valid, err, warn = cog_validate(raster_rgb)
+    assert valid
+    assert not err
+    assert not warn
+
+    valid, err, warn = cog_validate(raster_no_ovr)
+    assert valid
+    assert len(warn) == 1
+    assert not err
+
+
 def test_cog_validate_validCreatioValid(monkeypatch):
     """Should work as expected (validate cogeo file)."""
     runner = CliRunner()

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
affine==2.4.0
annotated-types==0.5.0
attrs==24.2.0
boto3==1.33.13
botocore==1.33.13
certifi @ file:///croot/certifi_1671487769961/work/certifi
cfgv==3.3.1
charset-normalizer==3.4.1
click==8.1.8
click-plugins==1.1.1
cligj==0.7.2
cogdumper==1.1.0
coverage==7.2.7
distlib==0.3.9
exceptiongroup==1.2.2
filelock==3.12.2
identify==2.5.24
idna==3.10
importlib-metadata==6.7.0
importlib-resources==5.12.0
iniconfig==2.0.0
jmespath==1.0.1
mercantile==1.2.1
morecantile==2.1.4
nodeenv==1.9.1
numexpr==2.8.6
numpy==1.21.6
packaging==24.0
platformdirs==4.0.0
pluggy==1.2.0
pre-commit==2.21.0
pydantic==2.5.3
pydantic_core==2.14.6
pyparsing==3.1.4
pystac==1.5.0
pytest==7.4.4
pytest-cov==4.1.0
python-dateutil==2.9.0.post0
PyYAML==6.0.1
rasterio==1.2.10
requests==2.31.0
-e git+https://github.com/cogeotiff/rio-cogeo.git@6fda1dc1904ea9317c776e709677af2cb2a698f6#egg=rio_cogeo
rio-color==1.0.4
rio-mucho==1.0.0
rio-tiler==2.1.4
s3transfer==0.8.2
six==1.17.0
snuggs==1.4.7
supermercado==0.2.0
tomli==2.0.1
typing_extensions==4.7.1
urllib3==1.26.20
virtualenv==20.26.6
zipp==3.15.0

name: rio-cogeo
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - affine==2.4.0
      - annotated-types==0.5.0
      - attrs==24.2.0
      - boto3==1.33.13
      - botocore==1.33.13
      - cfgv==3.3.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - click-plugins==1.1.1
      - cligj==0.7.2
      - cogdumper==1.1.0
      - coverage==7.2.7
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.12.2
      - identify==2.5.24
      - idna==3.10
      - importlib-metadata==6.7.0
      - importlib-resources==5.12.0
      - iniconfig==2.0.0
      - jmespath==1.0.1
      - mercantile==1.2.1
      - morecantile==2.1.4
      - nodeenv==1.9.1
      - numexpr==2.8.6
      - numpy==1.21.6
      - packaging==24.0
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - pre-commit==2.21.0
      - pydantic==2.5.3
      - pydantic-core==2.14.6
      - pyparsing==3.1.4
      - pystac==1.5.0
      - pytest==7.4.4
      - pytest-cov==4.1.0
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.1
      - rasterio==1.2.10
      - requests==2.31.0
      - rio-color==1.0.4
      - rio-mucho==1.0.0
      - rio-tiler==2.1.4
      - s3transfer==0.8.2
      - six==1.17.0
      - snuggs==1.4.7
      - supermercado==0.2.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - urllib3==1.26.20
      - virtualenv==20.26.6
      - zipp==3.15.0
prefix: /opt/conda/envs/rio-cogeo

tests/test_validate.py::test_cog_validate_valid tests/test_validate.py::test_cog_validate_return
tests/test_validate.py::test_cog_validate_validCreatioValid
rio_cogeo/cogeo.py rio_cogeo/scripts/cli.py
rio_cogeo/cogeo.py rio_cogeo/scripts/cli.py